Organizing Projects

GWT projects can be organized in a variety of ways. However, particular conventions are encouraged to make it easy to identify which code is intended to run on the client browser, the server, or both.

This section describes the fundamentals of project organization with GWT as well as the recommended conventions.

  1. HTML Host Pages
  2. Standard Directory and Package Layout
  3. Modules: Units of configuration
  4. Module XML files
  5. How do I know which GWT modules I need to inherit?
  6. Automatic Resource Inclusion
  7. Filtering Public and Source Packages
  8. The Bootstrap Sequence

HTML Host Pages

GWT modules are stored on a web server as a set of JavaScript and related files. In order to run the module, it must be loaded from a web page of some sort. Any HTML page can include a GWT application via a SCRIPT tag. This HTML page is referred to as a host page from the GWT application's point of view. A typical HTML host page for an application written with GWT from scratch might not include any visible HTML body content at all. The example below shows how to embed a GWT application that will use the entire browser window.


  
  
    
    
    
    
    
    
    
    Calendar App
    
  
  
   
    
    
    
    
    
    
    
    
    
    
  
 

Note that the body of the page contains only a SCRIPT tag and an IFRAME tag. It is left to the GWT application to then fill in all the visual content.

But GWT was designed to make it easy to add GWT functionality to existing web applications with only minor changes. It is possible to allow the GWT module to selectively insert widgets into specific places in an HTML page. To accomplish this, use the id attribute in your HTML tags to specify a unique identifier that your GWT code will use to attach widgets to that HTML element. For example:


    
    

Notice that the td tags include an id attribute associated with them. This attribute is accessible through the DOM class. You can easily attach widgets using the method RootPanel.get(). For example:

final Button button = new Button("Click me");
    final Label label = new Label();

    ...

    RootPanel.get("slot1").add(button);
    RootPanel.get("slot2").add(label);

In this manner, GWT functionality can be added as just a part of an existing page, and changing the application layout can be done in plain HTML. The I18N sample uses this technique heavily.

A host HTML page does not have to be static content. It could also be generated by a servlet, or by a JSP page.

Standard Directory and Package Layout

GWT projects are overlaid onto Java packages such that most of the configuration can be inferred from the classpath and the module definitions.

img

Guidelines

If you are not using the Command-line tools to generate your project files and directories, here are some guidelines to keep in mind when organizing your code and creating Java packages.

  1. Under the main project directory create the following directories:
    • src folder - contains production Java source
    • war folder - your web app; contains static resources as well as compiled output
    • test folder - (optional) JUnit test code would go here
  2. Within the src package, create a project root package, and within that create a client package.
  3. If you have server-side code, also create a server package to differentiate between the client-side code (which is translated into JavaScript) from the server-side code (which is not).
  4. Within the project root package, place one or more module definitions.
  5. In the war directory, place any static resources (such as the host page, style sheets, or images).
  6. Within the client and server packages, you are free to organize your code into any subpackages you require.

Example: GWT standard package layout

For example, all the files for the "DynaTable" sample are organized in a main project directory also called "DynaTable".

  • Java source files are in the directory: DynaTable/src/com/google/gwt/sample/dynatable
  • The module is defined in the XML file: DynaTable/src/com/google/gwt/sample/dynatable/DynaTable.gwt.xml
  • The project root package is: com.google.gwt.sample.dynatable
  • The logical module name is: com.google.gwt.sample.dynatable.DynaTable

The src directory

The src directory contains an application's Java source files, the module definition, and external resource files.

Package File Purpose
com.google.gwt.sample.dynatable The project root package contains module XML files.
com.google.gwt.sample.dynatable DynaTable.gwt.xml Your application module. Inherits com.google.gwt.user.User and adds an entry point class, com.google.gwt.sample.dynatable.client.DynaTable.
com.google.gwt.sample.dynatable.public Static resources that are loaded programmatically by GWT code. Files in the public directory are copied into the same directory as the GWT compiler output.
com.google.gwt.sample.dynatable.public logo.gif An image file available to the application code. You might load this file programmatically using this URL: GWT.getModuleBaseForStaticFiles() + "logo.gif".
com.google.gwt.sample.dynatable.client Client-side source files and subpackages.
com.google.gwt.sample.dynatable.client DynaTable.java Client-side Java source for the entry-point class.
com.google.gwt.sample.dynatable.client SchoolCalendarService.java An RPC service interface.
com.google.gwt.sample.dynatable.server Server-side code and subpackages.
com.google.gwt.sample.dynatable.server SchoolCalendarServiceImpl.java Server-side Java source that implements the logic of the service.

The war directory

The war directory is the deployment image of your web application. It is in the standard expanded war format recognized by a variety of Java web servers, including Tomcat, Jetty, and other J2EE servlet containers. It contains a variety of resources:

  • Static content you provide, such as the host HTML page
  • GWT compiled output
  • Java class files and jar files for server-side code
  • A web.xml file that configures your web app and any servlets

A detailed description of the war format is beyond the scope of this document, but here are the basic pieces you will want to know about:

Directory File Purpose
DynaTable/war/ DynaTable.html A host HTML page that loads the DynaTable app.
DynaTable/war/ DynaTable.css A static style sheet that styles the DynaTable app.
DynaTable/war/dynatable/ The DynaTable module directory where the GWT compiler writes output and files on the public path are copied. NOTE: by default this directory would be the long, fully-qualified module name com.google.gwt.sample.dynatable.DynaTable. However, in our GWT module XML file we used the rename-to="dynatable" attribute to shorten it to a nice name.
DynaTable/war/dynatable/ dynatable.nocache.js The "selection script" for DynaTable. This is the script that must be loaded from the host HTMLto load the GWT module into the page.
DynaTable/war/WEB-INF All non-public resources live here, see the servlet specification for more detail.
DynaTable/war/WEB-INF web.xml Configures your web app and any servlets.
DynaTable/war/WEB-INF/classes Java compiled class files live here to implement server-side functionality. If you're using an IDE set the output directory to this folder.
DynaTable/war/WEB-INF/lib Any library dependencies your server code needs goes here.
DynaTable/war/WEB-INF/lib gwt-servlet.jar If you have any servlets using GWT RPC, you will need to place a copy of gwt-servlet.jar here.

The test directory

The test directory contains the source files for any JUnit tests.

Package File Purpose
com.google.gwt.sample.dynatable.client Client-side test files and subpackages.
com.google.gwt.sample.dynatable.client DynaTableTest.java Test cases for the entry-point class.
com.google.gwt.sample.dynatable.server Server-side test files and subpackages.
com.google.gwt.sample.dynatable.server SchoolCalendarServiceImplTest.java Test cases for server classes.

Modules: Units of configuration

Individual units of GWT configuration are called modules. A module bundles together all the configuration settings that your GWT project needs:

  • inherited modules
  • an entry point application class name; these are optional, although any module referred to in HTML must have at least one entry-point class specified
  • source path entries
  • public path entries
  • deferred binding rules, including property providers and class generators

Modules are defined in XML and placed into your project's package hierarchy. Modules may appear in any package in your classpath, although it is strongly recommended that they appear in the root package of a standard project layout.

Entry-Point Classes

A module entry-point is any class that is assignable to EntryPoint and that can be constructed without parameters. When a module is loaded, every entry point class is instantiated and its EntryPoint.onModuleLoad() method gets called.

Source Path

Modules can specify which subpackages contain translatable source, causing the named package and its subpackages to be added to the source path. Only files found on the source path are candidates to be translated into JavaScript, making it possible to mix client-side and server-side code together in the same classpath without conflict. When module inherit other modules, their source paths are combined so that each module will have access to the translatable source it requires.

The default source path is the client subpackage underneath where the Module XML File is stored.

Public Path

Modules can specify which subpackages are public, causing the named package and its subpackages to be added to the public path. The public path is the place in your project where static resources referenced by your GWT module, such as CSS or images, are stored. When you compile your application into JavaScript, all the files that can be found on your public path are copied to the module's output directory. When referencing public resources in client code (for example, setting the URL of an Image widget, you should construct the URL like this: GWT.getModuleBaseForStaticFiles() + "resourceName.png". When referencing public resources from a Module XML File, just use the relative path within the public folder, the module's base URL will be prepended automatically. When a module inherits other modules, their public paths are combined so that each module will have access to the static resources it expects.

The default public path is the public subdirectory underneath where the Module XML File is stored.

Defining a module: format of module XML files

Modules 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:


    
    
 

Loading modules

Module 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...

~/src/com/example/cal/Calendar.gwt.xml

...then the logical name of the module is:

com.example.cal.Calendar

Renaming modules

The element supports an optional attribute rename-to that causes the compiler to behave as though the module had a different name than the long, fully-qualified name. Renaming a module has two primary use cases:

  • to have a shorter module name that doesn't reflect the actual package structure, this is the most typical and recommended use case
  • to create a "working module" to speed up development time by restricting the number of permutations

com.foo.WorkingModule.gwt.xml:


  
  
  

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. (Of course, if com.foo.MyModule was itself renamed, you would just copy its rename-to attribute.)

Dividing code into multiple modules

Creating 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 GWT (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 entry would be needed:


...
    

Loading multiple modules in an HTML host page

If you have multiple GWT modules in your application, there are two ways to approach loading them.

  1. Compile each module separately and include each module with a separate

    The following principles are needed to understand the sequence of operations that will occur in this page: