How to use GWT 2.0 with Maven and Generate SOYC Reports
One of the most interesting features coming in GWT 2.0 is code splitting and the ability to use GWT.runAsync() to reduce the size of your application's initial download. This week, I learned how to use GWT 2.0 with my GWT 1.6/Maven project. Below are instructions on how to build and use the latest GWT with Maven.
- Checkout GWT and setup GWT_TOOLS.
- Set a GWT_VERSION environment variable to 2.0.0-SNAPSHOT (export GWT_VERSION=2.0.0-SNAPSHOT).
- Build GWT with the ant command.
- After building completes, install the GWT artifacts into your local Maven repository using the following commands:
mvn install:install-file -DgroupId=com.google.gwt \ -DartifactId=gwt-user -Dversion=2.0.0-SNAPSHOT \ -Dpackaging=jar -Dfile=build/lib/gwt-user.jar mvn install:install-file -DgroupId=com.google.gwt \ -DartifactId=gwt-servlet -Dversion=2.0.0-SNAPSHOT \ -Dpackaging=jar -Dfile=build/lib/gwt-servlet.jar mvn install:install-file -DgroupId=com.google.gwt \ -DartifactId=gwt-dev -Dversion=2.0.0-SNAPSHOT \ -Dclassifier=mac -Dpackaging=jar -Dfile=build/lib/gwt-dev-mac.jar mkdir temp tar -zxf build/dist/gwt-mac-2.0.0-SNAPSHOT.tar.gz -C temp cd temp/gwt-mac-2.0.0-SNAPSHOT zip -0 gwt-mac-2.0.0-SNAPSHOT.zip lib*.jnilib cd ../.. mvn install:install-file -DgroupId=com.google.gwt \ -DartifactId=gwt-dev -Dversion=2.0.0-SNAPSHOT \ -Dclassifier=mac-libs -Dpackaging=zip \ -Dfile=temp/gwt-mac-2.0.0-SNAPSHOT/gwt-mac-2.0.0-SNAPSHOT.zip
Thanks to Jason for his help with this script. - Modify the pom.xml of your GWT project to use the the gwt-maven-plugin from Codehaus. Of course, you'll need to modify the <runTarget> to fit your project.
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>gwt-maven-plugin</artifactId> <version>1.1</version> <configuration> <runTarget>org.appfuse.gwt.mvc.${entry.point}/${entry.point}.html</runTarget> </configuration> <executions> <execution> <goals> <goal>compile</goal> <goal>test</goal> </goals> </execution> </executions> </plugin>
- Modify your dependencies to match the ones below. With the Codehaus plugin, dependencies are much more concise.
<dependency> <groupId>com.google.gwt</groupId> <artifactId>gwt-servlet</artifactId> <version>${gwt.version}</version> <scope>compile</scope> </dependency> <dependency> <groupId>com.google.gwt</groupId> <artifactId>gwt-user</artifactId> <version>${gwt.version}</version> <scope>provided</scope> </dependency>
- Add <gwt.version>2.0.0-SNAPSHOT</gwt.version> to the properties section of your pom.xml.
- At this point, you should be able to compile your project with mvn gwt:compile and run it in hosted mode using mvn gwt:run.
Generate SOYC Reports
In Google's code splitting documentation, it mentions The Story of Your Compile (SOYC). From the documentation:
To obtain a SOYC report for your application, there are two steps necessary. First, add -soyc to the compilation options that are passed to the GWT compiler. This will cause the compiler to emit raw information about the compile to XML files in an -aux directory beside the rest of the compiled output. In that directory, you will see an XML file for each permutation and a manifest.xml file that describes the contents of all the others.
The second step is to convert that raw information into viewable HTML. This is done with the SoycDashboard tool.
The first step is not currently possible with the gwt-maven-plugin, so I created a patch for it.
If you patch the gwt-maven-plugin and install it locally, make sure and change the version in your pom.xml to 1.2-SNAPSHOT.
To use the SoycDashboard tool, you'll need to install the gwt-soyc-vis.jar.
mvn install:install-file -DgroupId=com.google.gwt \ -DartifactId=gwt-soyc-vis -Dversion=2.0.0-SNAPSHOT \ -Dpackaging=jar -Dfile=build/lib/gwt-soyc-vis.jar
Now you can generate SOYC reports with mvn gwt:compile -Dgwt.compiler.soyc=true. You can also add <soyc>true</soyc> to the <configuration> section of the gwt-maven-plugin.
The second step (converting the raw information into viewable HTML) is possible using java from the command-line, or by using the exec-maven-plugin. Here's the (lengthy) command-line version:
java -Xmx1024m -cp /Users/mraible/.m2/repository/com/google/gwt/gwt-soyc/2.0.0-SNAPSHOT/gwt-soyc-2.0.0-SNAPSHOT.jar:/Users/mraible/.m2/repository/com/google/gwt/gwt-dev/2.0.0-SNAPSHOT/gwt-dev-2.0.0-SNAPSHOT-mac.jar com.google.gwt.soyc.SoycDashboard -resources ~/.m2/repository/com/google/gwt/gwt-soyc/2.0.0-SNAPSHOT/gwt-soyc-2.0.0-SNAPSHOT.jar -out target/soyc-report target/extra/org.appfuse.gwt.mvc.MVC/soycReport/stories0.xml.gz target/extra/org.appfuse.gwt.mvc.MVC/soycReport/dependencies0.xml.gz target/extra/org.appfuse.gwt.mvc.MVC/soycReport/splitPoints0.xml.gz
In this example, I'm using the files from stories0.xml.gz, dependencies0.xml.gz, splitPoints0.xml.gz. In the soycReport output directory, there's 5 of each these files and I'm not sure what the difference between reports is. Hopefully someone on the GWT team can elaborate. The exec-maven-plugin version is as follows:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.1</version> <configuration> <executable>java</executable> <arguments> <argument>-cp</argument> <argument> ${settings.localRepository}/com/google/gwt/gwt-soyc/2.0.0-SNAPSHOT/gwt-soyc-2.0.0-SNAPSHOT.jar:${settings.localRepository}/com/google/gwt/gwt-dev/2.0.0-SNAPSHOT/gwt-dev-2.0.0-SNAPSHOT-${platform}.jar </argument> <argument>com.google.gwt.soyc.SoycDashboard</argument> <argument>-out</argument> <argument>target/soyc-report</argument> <argument>-resources</argument> <argument> ${settings.localRepository}/com/google/gwt/gwt-soyc/2.0.0-SNAPSHOT/gwt-soyc-2.0.0-SNAPSHOT.jar </argument> <argument>${project.build.directory}/extra/org.appfuse.gwt.mvc.MVC/soycReport/stories0.xml.gz</argument> <argument>${project.build.directory}/extra/org.appfuse.gwt.mvc.MVC/soycReport/dependencies0.xml.gz</argument> <argument>${project.build.directory}/extra/org.appfuse.gwt.mvc.MVC/soycReport/splitPoints0.xml.gz</argument> </arguments> </configuration> </plugin>
After configuring this plugin in your project, you should be able to run mvn gwt:compile exec:exec and open the generated report (at target/soyc-report/SoycDashboard-index.html). Currently, there doesn't seem to be much documentation on SOYC. Fred Sauer's recent presentation talks a bit about SOYC and GWT.runAsync(), but that's about it.
To figure out how to use GWT 2.0 with Maven, I used my GWT MVC Example project. The first SOYC report I generated said the initial download was 108,967 KB. To integrate GWT.runAsync(), I modified all the project's controllers so their handleEvent() methods changed from this:
public void handleEvent(AppEvent> event) { onViewHome(event); }
To this:
public void handleEvent(final AppEvent> event) { GWT.runAsync(new RunAsyncCallback() { public void onFailure(Throwable throwable) { Window.alert(throwable.getMessage()); } public void onSuccess() { onViewHome(event); } }); }
When I generated a new SOYC report, the initial download size was reduced to 56,718 KB. Furthermore, I was able to see that my "Leftovers code" consisted of 63,175 KB. I'm sure there's better ways to split my project using GWT.runAsync(), but I'm happy to see I was able to reduce the initial download by 50%.
If you'd like to try GWT 2.0, you can can download my gwt-mvc example project. To build/run this project, you'll need to 1) build and install GWT, 2) patch gwt-maven-plugin and 3) run mvn gwt:compile exec:exec to generate the SOYC report. In an ideal world, the gwt-maven-plugin can be enhanced to generate the SOYC report (rather than using the exec-maven-plugin). In the meantime, I think it's pretty cool that you can try out GWT 2.0 features while they're still being developed.
Posted by Daniel Wellman on June 26, 2009 at 11:20 AM MDT #
Hi,
just to let you know you don't have to install the GWT SDK artifacts in your local repository if you built it by yourself,
just set the plugin <gtwHome> parameter to point to the built staging folder :
Your patch has been applied, and a soyc report mojo is now in SVN (but need some more time to get fully integrated in Maven generated site)
Cheers
Posted by nicolas de loof on June 26, 2009 at 12:56 PM MDT #
Posted by William Shields on June 27, 2009 at 12:38 AM MDT #
Hi All
Could anyone put up the patches maven gwt plugin, so everybody who reads this post doesnt have to do it? Just an idea :)...
/Murat
Posted by Murat on June 29, 2009 at 12:57 PM MDT #
Posted by Alexandre de Pellegrin on June 30, 2009 at 08:08 AM MDT #
I think a little explanation is required as to what is happening in the following portion of your first script.
My problems are
1. build/dist/gwt-mac-2.0.0-SNAPSHOT.tar.gz does not exist after a build. What generates this file? What's in it? The only *tar.gz files that exist are
2. What lib*.jnilib files are required?. The only ones I find are
Thanks
Posted by Paul Wills on July 01, 2009 at 12:23 PM MDT #
Hi,
Nice post! I've tried it and it works until I want to lauch the project with mvn gwt:run. I get:
I am on Linux (Ubuntu 9 kernel), with Firefox 3.0.11. Do you have any idea what I should do to make it work? Any help will be *GREATLY* appreciated. :)
Thanks.
Evelyne
Posted by Evelyne on July 06, 2009 at 03:08 PM MDT #
Hi again,
I've solved the issue. After a few painful hours, I've added a dependency to the gwt-dev-oophm.jar in the pom of my project:
I can confirm it works fine now on Ubuntu 9, Firefox 3.0.11.
Hope this helps.
Evelyne
Posted by Evelyne on July 07, 2009 at 10:47 AM MDT #
Posted by Chris Jones on August 05, 2009 at 08:51 PM MDT #
Posted by Alex on August 20, 2009 at 08:13 AM MDT #
Posted by touchdsky on October 29, 2009 at 06:20 AM MDT #