0

Suppose I have a project structure that looks roughly like this:

{module-package}.webapp  
    module.gwt.xml
{module-package}.webapp.client
    Client.java
    UsedByClient.java
    NotUsedByClient.java

And the module.gwt.xml file has:

<source path='client'/>
<entry-point class='{module-package}.webapp.client.Client'/>

When I compile this project using GWT, how much of the Java code will be compiled into Javascript?

  • Is NotUsedByClient.java included, even though the entry point doesn't reference it?
  • Is UsedByClient.java fully or partially included? E.g. if it has method m() which isn't called by Client, will m be compiled or not?

The motivation is that unfortunately I'm working with a legacy codebase that has server-side code living alongside client-side code in the same package and it would be some work to separate them. The server-side code isn't used by the client, but I'm concerned that GWT might compile it to Javascript where someone might notice it and try to reverse engineer it.

Kevin K
  • 9,344
  • 3
  • 37
  • 62

2 Answers2

5

All of the above and more happen:

  • unreferenced classes are removed
  • unreferenced methods and fields are removed
  • constants may be inlined
  • various operations on constants (like !, ==, +, &&, etc) may be simplified (based on some field always being null, or true, etc)
  • un-overridden methods may be made final...
  • ...and final methods may be made static in certain situations (leading to smaller callsites, and no "this" reference inside that method)...
  • and small, frequently called static methods may be inlined

And this process repeats, with even more optimizations that I skipped, to further assist in removing code, both big and small. At the end, all classes, methods, fields, and local variables are renamed in a way to further reduce output size, including reordering methods in the output so that they are ordered by length, letting gzip more efficiently compress your content on the way to the client.

So while some aspects of your code could be reverse engineered (just like any machine code could be reverse engineered), code which isn't referenced won't be available, and code which is may not even be readable.

Colin Alworth
  • 17,801
  • 2
  • 26
  • 39
  • Thanks Colin, is there any way to review what types and members are retained by GWT in the final compilation? I am fairly certain the server-side code isn't referenced, but it would be nice if I could confirm that. – Kevin K Nov 17 '17 at 02:27
  • 1
    There is! Check out the SOYC feature: Story Of Your Compile. This tells you how many bytes each included method ended up being, and why it is still included in the output. That said, the best way to avoid server side code is to not include it in the same specified packages (forcing the compiler to not be aware that it exists at all), or annotating it with `@GwtIncompatible`. Additionally, if you have code that can't be translated, this may slow down dev mode dramatically, as it retries to compile it for every single refresh. – Colin Alworth Nov 17 '17 at 03:00
0

I somehow managed to stumble upon a 'deep dive' video presentation on the compiler by one of the GWT engineers which has an explanation: https://youtu.be/n-P4RWbXAT8?t=865

Key points:

  • One of the compiler optimizations is called Pruner and it will "Traverse all reachable code from entrypoint, delete everything else (uses ControlFlowAnalyzer)"
  • It is actually an essential optimization because without it, all GWT apps would need to include gwt-user.jar in its entirety, which would greatly increase app sizes.

So it seems the GWT compiler does indeed remove unused code.

Kevin K
  • 9,344
  • 3
  • 37
  • 62