Tips on organizing GWT modules
Posted by David Chandler on November 19, 2009
My current project is at the point where I’m starting to work on an administrative UI. I wanted to package it as a separate GWT module in order to not clutter up the main application module. There is some code such as the domain model that is shared between the main app and the admin code, so the question is how to organize the modules in order to share code between them.
My first attempt was to have the admin module simply inherit the main app module named ROA in admin.gwt.xml, like this:
<inherits name="com.roa.app.ROA" />
This had two undesired results:
- Both modules declare an entry-point, so GWT tries to load both, beginning with the inherited module.
- At GWT compile time, all the code from the inherited module was duplicated under the admin module in the war structure.
admin.gwt.xml app.gwt.xml common.gwt.xml
Admin and app each have entry points and inherit the common module, which does not define an entry point. This works fine.
In the common module, I use the source tag to include multiple directories instead of just the default client directory. Note that if you specify one or more source directories, GWT no longer compiles the client directory by default, so you have to explicitly include it, as well:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.7.1//EN" "http://google-web-toolkit.googlecode.com/svn/tags/1.7.1/distro-source/core/src/gwt-module.dtd"> <module> <inherits name="com.google.gwt.user.User" /> <source path="client" /> <source path="domain" /> <source path="presenter" /> </module>
Also, I moved the “public” directory containing CSS and images from the admin and app packages into the common module, and discovered that GWT does not create a “common” directory in the war, but rather copies the contents of the public folder from the inherited common module into both the admin and app module directories. That’s OK, though, as my CSS and images now exist in only one place in source control.
A final note: thank goodness for Eclipse refactoring tools. The easiest way to move a package (say, com.roa.app.domain to com.roa.common.domain) is to select it in the Project Explorer, then right-click, Refactor, and Rename… It’s a bit non-intuitive to use Rename rather than the Move command, but the latter appears to work only for moving packages to another project or source folder, whereas rename allows you to “move” it within the current source folder. Eclipse automatically fixes all the package and import declarations in affected code (whew!).