Note: "Hosted mode" and "web mode" have been renamed development mode and production mode, respectively.
During its bootstrap process, a GWT application goes through a series of sometimes cryptically-named files. These files, generated by the GWT Compiler, usually seem strange to developers new to GWT. To effectively deploy a GWT application, however, it is necessary to understand these files so that they can be placed appropriately on the web server.
The important files produced by the GWT Compiler are:
Each of the items listed above is described below. However, first it's important to understand the concept of deferred binding since that notion is at the heart of the bootstrap process injected into the <Module Name>.nocache.js file, so you might want to read a bit about deferred binding before continuing.
Before explaining what each file does, it's also useful to summarize the overall bootstrap procedure for a GWT application:
That's the process in a nutshell. For an example the bootstrap process for a complete GWT application, check out the Developer Guide example. The sections below describe each of the GWT application files in detail.
Because of this uniqueness guarantee, it is safe (and indeed preferable) for browsers to cache these files, which is reflected in their .cache.html file extension.
The "nocache" file is where Deferred Binding occurs. Before the application can run, any dynamically-bound code must be resolved. This might include browser-specific versions of classes, the specific set of string constants appropriate to the user's selected language, and so on. In Java, this would be handled by simply loading an appropriate service-provider class that implements a particular interface. To maximize performance and minimize download size, however, GWT does this selection up-front in the "nocache" file.
The reason the file is named ".nocache.html" is to indicate that the file should never be cached. That is, it must be downloaded and executed again each time the browser starts the GWT application. The reason it must be re-downloaded each time is that the GWT Compiler regenerates it each time, but under the same file name. If the browsers were allowed to cache the file, they might not download the new version of the file, when the GWT application was recompiled and redeployed on the server. To help prevent caching, the code in gwt.js actually appends an HTTP GET parameter on the end of file name containing a unique timestamp. The browser interprets this as a dynamic HTTP request, and thus should not load the file from cache.
In previous versions of GWT, if your application used GWT RPC, the types that you wanted to serialize across the wire had to implement the IsSerializable interface. As of GWT 1.4, types that implement the java.io.Serializable interface now also qualify for serialization over RPC, with some conditions.
One of these conditions is that the types that you would like to serialize over the wire must be included in the .gwt.rpc file generated by the GWT compiler. The .gwt.rpc file serves as a serialization policy to indicate which types implementing java.io.Serializable are allowed to be serialized over the wire. For more details on this and other conditions to use Serializable types in GWT RPC, check out this FAQ.
That is the story behind the somewhat strange GWT file names. The <module>.nocache.js performs the deferred binding resolution and selects a cache file based on the execution context
The bootstrap process of a GWT application involves a <Module Name>.nocache.js file, and a number of .cache.html files. In the development mode environment, these applications are automatically placed in a war style directory based on the output directory specified in the -out argument. For instance, if the -out argument specified in your build.xml development target reads myapp, then the development mode process will read your host HTML page at /test/war/MyApp.html.
When a GWT application is deployed, however, it must coexist with the rest of the web site. To correctly integrate a GWT application into a web site's file structure, the site administrator must understand how GWT applications bootstrap. Otherwise, the files may not be at the locations where the GWT infrastructure expects to find them, and the application will not load. The details below describe each of these principle components, as well as where they should be located to properly load up your GWT application
In the GWT 1.4 bootstrap model, GWT expects to find all its files in the same path as the <module>.nocache.js file. For example, let's suppose your GWT Module's name is com.company.app.MyApp, and that the host HTML file is at http://host.domain.tld/myApp/index.html. Further suppose that the <module>.nocache.js and other files generated by the GWT compiler are in the same path as the host HTML file. With this setup, the following sequence of requests will occur:
For an example of the bootstrap sequence for a complete GWT application, check out the Developer Guide docs.
The configuration above may not work in your own case. For example, for organizational reasons you might want to place the host HTML page at the root path, but place the GWT-related files at a different location, such as /gwt-files.
To relocate the GWT application files to the /gwt-files path, all you need to do is update the <script> tag referencing the <module>.nocache.js file to include the relative (or absolute) path to the file. The files generated by the GWT compiler, including the .cache.html files, must also reside at the same path as the <module>.nocache.js file.
In this case if your GWT Module is com.company.app.MyApp, the <script> tag in the host page (index.html) would be:
The example above would result in the following file download sequence:
Usually applications will need additional content, such as images and CSS files, and of course dynamic resources such as RPC or JSON URLs. The techniques described above will change not only the path used to fetch GWT's application files, but also the value returned by the GWT.getModuleBaseURL() and GWT.getModuleBaseForStaticFiles() methods. If your application uses that method to construct URLs to additional resources, be sure that the resources are located in the appropriate directory. For example, if you remap your GWT files to '/gwt-files/', but your host page is /index.html, then the code GWT.getModuleBaseForStaticFiles() + "myImage.png" will result in the URL /gwt-files/myImage.png.
It's important to take care if your code refers to resources using GWT.getModuleBaseURL() or GWT.getModuleBaseForStaticFiles(). This is an especially common concern for those using Java Servlets, because the Servlet mapping must be set appropriately in the module XML file (.gwt.xml).
If you prefer not to have GWT obfuscate its output, then you can use the -style flag on the GWT Compiler. This flag has one of three possible values:
If you are compiling a large application, you may find that compiling to production mode takes a long time. One issue is that the compiler actually builds several versions of your application based on client properties for locale and browser. For deployment, this is crucial, but for everyday development, you are probably only using a single browser and locale. If that is the case, then you can take a shortcut and compile only a single permutation during the development cycle.
Creating this shortcut setup requires creating a new module and manipulating the client properties. What you need to do is to create a module that inherits from your existing module that specifies exact values for client properties that you want to nail down. Let's use Hello as an example...
You can do the same thing for locale or any other client property. The subsystem that generates all those permutations is completely extensible, so this technique is a general one. You can thus keep two module XML files in parallel, one for solid development to be tested on all browsers, and another working copy with most permutations suppressed for draft code.
Hopefully this example also starts to show that the idea of a module isn't as trivial as it might seem at first. Modules play an important role letting you determine what exactly you're trying to build. You can have as many modules as you want for different configurations for the same code base. You can imagine module variations like "MySuperBigModuleWithDebuggingAndLoggingTurnedOn.gwt.xml".
Starting with GWT 1.6, the compiler generates output in a directory structure following the Web Application Archive (WAR) standard layout. This feature makes it easier to deploy your application on any servlet container, like Jetty, Tomcat, or the Google App Engine Java runtime. See Chapter 9 of the Servlet 2.5 API specification for more details on the WAR standard layout.
Following the convention, developers may place their static resources, including their host HTML page, in the war/<appname> directory, where <appname> is the name you specify in your module XML file via the rename-to attribute (i.e. <module rename-to="myapp">). The question has come up as to whether the GWT compiler requires this resources to be present in the same war directory structure that will be used for output, or if it is possible to specify a separate input source that could be used to read in required resources. The answer: it is indeed possible to use a totally independent input source and only use the WAR directory uniquely for the compiler's generated output. Since the GWT build process now uses the Apache Ant build tool, all you would need to do is add a copy target in your project build script (build.xml) that will copy and place the required static resources in the final war output directory.
For example, here is the build.xml file generated by the GWT webAppCreator script:
Let's suppose that the static resources that you want to copy over are located in the src/com/myapp/resources folder. You could define a copy target that takes these resources and copies them over to the war output directory like so:
<target name="copyresources" description="Copy static resources to war output directory"> <copy todir="war/myapp"> <fileset dir="src/com/myapp/resources"> <include name="**/*"/> </fileset> </copy> </target>
Lastly, update the gwtc target to depend on the newly created copyresources target:
At this point, you should be ready to go. That is, of course, if you're planning on using Java on the server-side. If you're deploying on a different server-side technology, the new WAR style directory probably isn't very interesting to you, but you can nonetheless treat the input and output directories separately, as well as extract what you need from the WAR output directory for whatever server-side your application uses.
Like in previous versions of GWT, you can always use the server-side of your choice to deploy your GWT application. The new WAR output directory structure that the GWT compiler uses to generate output was introduced in GWT 1.6 to make it easier for developers who use Java on the server-side to deploy their applications directly from the generated output, as is the case for the Google Plugin for Eclipse.
All you need to do to deploy your GWT application your custom web server is to extract the important files generated during the GWT compilation and place them on your web server. These files are the <appname>.nocache.js and other <md5>.cache.html files. For more information on the generated files, check out this FAQ which describes them in more detail. The generated JS and HTML files are placed in the war/<appname> folder during compilation. All you need to do is copy these files to your web server's active directory, as well as any other static resources required by your application like images or stylesheets, and you're done.
See GWT Compiler Options.