GWT 是否会在编译期间删除未使用的 类?
Does GWT remove unused classes during compilation?
假设我有一个大致如下所示的项目结构:
{module-package}.webapp
module.gwt.xml
{module-package}.webapp.client
Client.java
UsedByClient.java
NotUsedByClient.java
module.gwt.xml
文件有:
<source path='client'/>
<entry-point class='{module-package}.webapp.client.Client'/>
当我使用 GWT 编译这个项目时,有多少 Java 代码会被编译成 Java 脚本?
- 是否包含
NotUsedByClient.java
,即使入口点未引用它?
-
UsedByClient.java
是全部还是部分包含在内?例如。如果它有 Client
没有调用的方法 m()
,是否会编译 m
?
动机是,不幸的是,我正在使用一个遗留代码库,该代码库的服务器端代码与客户端代码一起生活在同一个包中,将它们分开需要一些工作。客户端不使用服务器端代码,但我担心 GWT 可能会将其编译为 Java 脚本,有人可能会注意到它并尝试对其进行逆向工程。
我以某种方式设法偶然发现了一位 GWT 工程师关于编译器的 'deep dive' 视频演示,其中有解释:https://youtu.be/n-P4RWbXAT8?t=865
要点:
- 编译器优化之一称为
Pruner
,它将 "Traverse all reachable code from entrypoint, delete everything else (uses ControlFlowAnalyzer)"
- 这实际上是一项重要的优化,因为如果没有它,所有 GWT 应用程序都需要完整地包含
gwt-user.jar
,这将大大增加应用程序的大小。
看来 GWT 编译器确实删除了未使用的代码。
发生以上所有情况以及更多情况:
- 未引用的 类 已删除
- 未引用的方法和字段已删除
- 常量可以内联
- 可以简化对常量(如 !、==、+、&& 等)的各种操作(基于某些字段始终为 null 或 true 等)
- 未重写的方法可能最终...
- ...并且最终方法在某些情况下可能会变成静态的(导致较小的调用点,并且该方法内部没有 "this" 引用)...
- 小的、经常调用的静态方法可以内联
并且重复此过程,我跳过了更多优化,以进一步帮助删除大小代码。最后,所有 类、方法、字段和局部变量都以进一步减小输出大小的方式重命名,包括在输出中重新排序方法,以便它们按长度排序,让 gzip 更有效地压缩您的内容在去客户的路上。
因此,虽然您的代码的某些方面可能会被逆向工程(就像任何机器代码都可能被逆向工程一样),但未被引用的代码将不可用,甚至可能不可读。
假设我有一个大致如下所示的项目结构:
{module-package}.webapp
module.gwt.xml
{module-package}.webapp.client
Client.java
UsedByClient.java
NotUsedByClient.java
module.gwt.xml
文件有:
<source path='client'/>
<entry-point class='{module-package}.webapp.client.Client'/>
当我使用 GWT 编译这个项目时,有多少 Java 代码会被编译成 Java 脚本?
- 是否包含
NotUsedByClient.java
,即使入口点未引用它? -
UsedByClient.java
是全部还是部分包含在内?例如。如果它有Client
没有调用的方法m()
,是否会编译m
?
动机是,不幸的是,我正在使用一个遗留代码库,该代码库的服务器端代码与客户端代码一起生活在同一个包中,将它们分开需要一些工作。客户端不使用服务器端代码,但我担心 GWT 可能会将其编译为 Java 脚本,有人可能会注意到它并尝试对其进行逆向工程。
我以某种方式设法偶然发现了一位 GWT 工程师关于编译器的 'deep dive' 视频演示,其中有解释:https://youtu.be/n-P4RWbXAT8?t=865
要点:
- 编译器优化之一称为
Pruner
,它将 "Traverse all reachable code from entrypoint, delete everything else (uses ControlFlowAnalyzer)" - 这实际上是一项重要的优化,因为如果没有它,所有 GWT 应用程序都需要完整地包含
gwt-user.jar
,这将大大增加应用程序的大小。
看来 GWT 编译器确实删除了未使用的代码。
发生以上所有情况以及更多情况:
- 未引用的 类 已删除
- 未引用的方法和字段已删除
- 常量可以内联
- 可以简化对常量(如 !、==、+、&& 等)的各种操作(基于某些字段始终为 null 或 true 等)
- 未重写的方法可能最终...
- ...并且最终方法在某些情况下可能会变成静态的(导致较小的调用点,并且该方法内部没有 "this" 引用)...
- 小的、经常调用的静态方法可以内联
并且重复此过程,我跳过了更多优化,以进一步帮助删除大小代码。最后,所有 类、方法、字段和局部变量都以进一步减小输出大小的方式重命名,包括在输出中重新排序方法,以便它们按长度排序,让 gzip 更有效地压缩您的内容在去客户的路上。
因此,虽然您的代码的某些方面可能会被逆向工程(就像任何机器代码都可能被逆向工程一样),但未被引用的代码将不可用,甚至可能不可读。