|
DevGuideModuleXml
Modules are defined in XML and placed into your project's package hierarchy.
Defining a module: format of module XML filesModules are defined in XML files with a file extension of .gwt.xml. Module XML files should reside in your project's root package. If you are using the standard project structure, your module XML can be as simple as the following example: <module>
<inherits name="com.google.gwt.user.User" />
<entry-point class="com.example.cal.client.CalendarApp" />
</module>Loading modulesModule XML files are found on the Java classpath. Modules are always referred to by their logical names. The logical name of a module is of the form pkg1.pkg2.ModuleName (although any number of packages may be present). The logical name includes neither the actual file system path nor the file extension. For example, if the module XML file has a file name of... $PP_OFF ~/src/com/example/cal/Calendar.gwt.xml ...then the logical name of the module is: $PP_OFF com.example.cal.Calendar Renaming modulesThe <module> element supports an optional attribute rename-to that causes the compiler to behave as though the module had the name specified. Renaming a module has two primary use cases:
com.foo.WorkingModule.gwt.xml: <module rename-to="com.foo.MyModule"> <inherits name="com.foo.MyModule" /> <set-property name="user.agent" value="ie6" /> <set-property name="locale" value="default" /> </module> When WorkingModule.gwt.xml is compiled, the compiler will produce only an ie6 variant using the default locale; this will speed up development compilations. The output from the WorkingModule.gwt.xml will be a drop-in replacement for MyModule.gwt.xml because the compiler will generate the output using the alternate name. To use a renamed module in hosted mode, it is necessary to use the "physical" name (i.e. com.foo.WorkingModule) in the URL path, while otherwise referring to com.foo.MyModule in the host HTML page. Dividing code into multiple modulesCreating a second module doesn't necessarily mean that that module must define an entry point. Typically, you create a new module when you want to package up a library of GWT code that you want to reuse in other GWT projects. An example of this is the Google API Library for Google Web Toolkit (GALGWT), specifically the Gears for GWT API binding. If you download the library and take a look at the gwt-google-apis/com/google/gwt/gears you'll find the Gears.gwt.xml file for the module which doesn't define an entry point. However, any GWT project that would like to use Gears for GWT will have to inherit the Gears.gwt.xml module. For example, a module named "Foo" might want to use GALGWT, so in Foo.gwt.xml an <inherits> entry would be needed: <module>
...
<inherits name='com.google.gwt.gears.Gears' />Loading multiple modules in an HTML host pageIf you have multiple GWT modules in your application, there are two ways to approach loading them.
The first approach of compiling each module separately might seem like a compelling modular approach. Unfortunately, this approach is probably worst for performance because two full applications will need to be downloaded. Furthermore, each module will contain redundant copies of GWT library code and possibly encounter conflicts when it comes to event handling. For these reasons, you should not use this approach without a compelling reason. Controlling compiler outputThe GWT compiler separates the act of compiling and packaging its output with the Linker subsystem. It is responsible for the final packaging of the JavaScript code and providing a pluggable bootstrap mechanism for any particular deployment scenario.
Several linkers are provided by Core.gwt.xml, which is automatically inherited by User.gwt.xml.
From Core.gwt.xml: <module> <define-linker name="std" class="com.google.gwt.dev.linker.IFrameLinker" /> <define-linker name="sso" class="com.google.gwt.dev.linker.SingleScriptLinker" /> <define-linker name="xs" class="com.google.gwt.dev.linker.XSLinker" /> <add-linker name="std" /> </module> Changing the desired linker in MyModule.gwt.xml: <module> <inherits name="com.google.gwt.core.Core" /> <add-linker name="xs" /> </module> Overriding one package implementation with anotherThe <super-source> tag instructs the compiler to "re-root" a source path. This is useful for cases where you want to be re-use an existing Java API for a GWT project, but the original source is not available or not translatable. A common reason for this is to emulate part of the JRE not implemented by GWT. For example, suppose you want implement the UUID class provided by the JRE under java.util. Assume your project's module file is com/example/myproject/MyProject.gwt.xml. Place the source for the UUID class into com/example/myproject/jre/java/util/UUID.java. Then add a line to MyProject.gwt.xml: <super-source path="jre" /> This tells the compiler to add all subfolders of com/example/myproject/jre/ to the source path, but to strip off the path prefix up to and including jre. As a result, com/google/myproject/gwt/jre/java/util/UUID.java will be visible to the compiler as java/util/UUID.java, which is the intended result. The GWT project uses this technique internally for the JRE emulation classes provided with GWT. One caveat specific to overriding JRE classes in this way is that they will never actually be used in hosted mode. In hosted mode, the native JRE classes always supersede classes compiled from source. The <super-source> element supports pattern-based filtering to allow fine-grained control over which resources get copied into the output directory during a GWT compile. XML Element ReferenceThis section documents the most commonly used elements in the module XML file.
If no <source> element is defined in a module XML file, the client subpackage is implicitly added to the source path as if <source path="client" /> had been found in the XML. This default helps keep module XML compact for standard project layouts.
If no <public> element is defined in a module XML file, the public subpackage is implicitly added to the public path as if <public path="public"> had been found in the XML. This default helps keep module XML compact for standard project layouts.
The <servlet> element applies only to GWT's embedded server server-side debugging feature.
Elements for Deferred BindingThe following elements are used for defining deferred binding rules. Deferred binding is not commonly used in user projects.
Defining conditionsThe <replace-with-class> and <generate-with-class> elements can take a <when...> child element that defines when this rule should be used, much like the WHERE predicate of an SQL query. The three different types of predicates are:
Several different predicates can be combined into an expression. Surround your <when...> elements using the following nesting elements begin/end tags:
Deferred Binding ExampleAs an example module XML file that makes use of deferred binding rules, here is a module XML file from the GWT source code, Focus.gwt.xml: <module>
<inherits name="com.google.gwt.core.Core" />
<inherits name="com.google.gwt.user.UserAgent" />
<!-- old Mozilla, and Opera need a different implementation -->
<replace-with class="com.google.gwt.user.client.ui.impl.FocusImplOld">
<when-type-is class="com.google.gwt.user.client.ui.impl.FocusImpl" />
<any>
<when-property-is name="user.agent" value="gecko" />
<when-property-is name="user.agent" value="opera" />
</any>
</replace-with>
<!-- Safari needs a different hidden input -->
<replace-with class="com.google.gwt.user.client.ui.impl.FocusImplSafari">
<when-type-is class="com.google.gwt.user.client.ui.impl.FocusImpl" />
<when-property-is name="user.agent" value="safari" />
</replace-with>
<!-- IE's implementation traps exceptions on invalid setFocus() -->
<replace-with class="com.google.gwt.user.client.ui.impl.FocusImplIE6">
<when-type-is class="com.google.gwt.user.client.ui.impl.FocusImpl" />
<any>
<when-property-is name="user.agent" value="ie6" />
</any>
</replace-with>
</module>
|
Sign in to add a comment
It would be nice if this page referenced the tech talk: Google I/O 2008 - Deferred Binding with GWT
See: http://www.youtube.com/watch?v=nvti32k4xyU
It should be stated explicitly that the <replace-with> element behaves as though there is an <all> element that wraps its children. Thus, the "old Mozilla" example acts as if you'd typed:
<!-- old Mozilla, and Opera need a different implementation --> <replace-with class="com.google.gwt.user.client.ui.impl.FocusImplOld"> <all> <when-type-is class="com.google.gwt.user.client.ui.impl.FocusImpl" /> <any> <when-property-is name="user.agent" value="gecko" /> <when-property-is name="user.agent" value="opera" /> </any> </all> </replace-with>