0

假设我有一个大致如下的项目结构:

{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 代码会被编译成 Javascript?

  • 是否NotUsedByClient.java包括在内,即使入口点没有引用它?
  • UsedByClient.java全部还是部分包括在内?例如,如果它有m()未被调用的方法,是否Clientm被编译?

动机是不幸的是,我正在使用一个遗留代码库,该代码库的服务器端代码与客户端代码一起存在于同一个包中,将它们分开需要一些工作。客户端不使用服务器端代码,但我担心 GWT 可能会将其编译为 Javascript,从而有人可能会注意到它并尝试对其进行逆向工程。

4

2 回答 2

5

以上所有以及更多情况都会发生:

  • 未引用的类被删除
  • 未引用的方法和字段被删除
  • 常量可以内联
  • 可以简化对常量的各种操作(如!、==、+、&& 等)(基于某些字段始终为 null 或 true 等)
  • 未覆盖的方法可能会成为最终方法...
  • ...在某些情况下,最终方法可能是静态的(导致更小的调用点,并且该方法内没有“this”引用)...
  • 小的、经常被调用的静态方法可以被内联

这个过程会重复,我跳过了更多的优化,以进一步帮助删除大小代码。最后,所有类、方法、字段和局部变量都被重命名以进一步减少输出大小,包括重新排序输出中的方法,以便它们按长度排序,让 gzip 更有效地压缩你的内容到客户端。

因此,虽然您的代码的某些方面可以被逆向工程(就像任何机器代码都可以被逆向工程一样),但未被引用的代码将不可用,甚至可能不可读的代码。

于 2017-11-16T22:38:01.007 回答
0

我不知何故偶然发现了一位 GWT 工程师对编译器的“深入了解”视频演示,其中有一个解释: https ://youtu.be/n-P4RWbXAT8?t=865

关键点:

  • 调用编译器优化之一,Pruner它将“从入口点遍历所有可访问的代码,删除其他所有内容(使用 ControlFlowAnalyzer)”
  • 这实际上是一项必不可少的优化,因为没有它,所有 GWT 应用程序都需要gwt-user.jar完整地包含在内,这将大大增加应用程序的大小。

所以看起来 GWT 编译器确实删除了未使用的代码。

于 2017-11-16T22:36:06.230 回答