My favorites | English | Sign in

Google Web Toolkit

Debugging and Compiling

  1. Debugging in Hosted Mode
    1. What are the language differences between web mode and hosted mode?
    2. How do I use EJBs in hosted mode?
    3. How do I use my own server in hosted mode instead of GWT's built-in Jetty instance?
    4. What are the options that can be passed to the HostedMode process?
  2. Compiling for Web Mode
    1. What's with all the cache/nocache stuff and weird filenames?
    2. How do I change the location of my cache/nocache HTML files?
    3. Why is my GWT-generated JavaScript gibberish?
    4. Can I speed up the GWT compiler?
    5. Is the war directory used by the GWT compiler as both an input and output directory to the compiler process?
    6. Does the new WAR output directory layout require me to use Java on the server-side?
    7. What are the options that can be passed to the Compiler process?

Debugging in Hosted Mode

What are the language differences between web mode and hosted mode?

Typically, if your code runs as intended in hosted mode and compiles to JavaScript without error, web mode behavior will be equivalent. Occasional different problems can cause subtle bugs to appear in web mode that don't appear in hosted mode. Fortunately those cases are rare.

A full list of known language-related "gotchas" is available in the GWT documentation.

How do I use EJBs in hosted mode?

GWT provides the -noserver option to the hosted mode shell script for this sort of thing.

The -noserver option instructs hosted mode to not start the embedded Jetty instance. In its place, you would run the J2EE container of your choice and simply use that in place of the embedded Jetty instance.

How do I use my own server in hosted mode instead of GWT's built-in Jetty instance?

If you do not need to use, or prefer not to use, the Jetty instance embedded in GWT's hosted mode to serve up your servlets for debugging, you can use the -noserver flag to prevent Jetty from starting, while still taking advantage of hosted mode for debugging your GWT client code.

If you need the -noserver option, it is likely because your server-side code that handles your XMLHTTPRequest data requests requires something more, or just something different than Jetty. Here are some example cases where you might need to use -noserver:

  • You need an EJB container, which the embedded Jetty server does not support.
  • You have an extensive Servlet configuration (with custom web.xml and possibly server.xml files) that is too inconvenient to use with the embedded Jetty.
  • You are not using J2EE on the server at all (for example, you might be using JSON with Python).

When using the -noserver flag, your external server is used by the GWT Hosted Mode browser to serve up both your dynamic content, and all static content (such as the GWT application's host page, other HTML files, images, CSS, and so on.) This allows you to structure your project files in whatever way is most convenient to your application and infrastructure.

Though your own external server handles all static content and dynamic resources, all browser application logic continues to be handled in Java, internal to hosted mode. This means that you can continue to debug your client-side code in Java as usual, but all server-side requests will be served by your web or application server of choice. (If you are using an IDE such as Eclipse configured to integrate with GWT's hosted mode for debugging, then using -noserver will prevent you from automatically debugging your server code in the same debugger instance you use to debug hosted mode. However, if the server software you use supports it, you can of course use an external debugging tools.)

Here is a step-by-step description of how to use -noserver:

  1. Configure your server however you need to; note the URL which contains the host page for your GWT application.
  2. Arrange all your static content files (such as the host HTML page, images, CSS, etc.) on the server however you like.
  3. Edit your hosted mode execution script (such as your Eclipse run configuration or the ant hosted build target generated by the GWT webAppCreator) and add or update the following options:
    • Add the -noserver command line argument.
    • Change the URL at the end of the argument list to match the URL you recorded in step #1.
  4. Re-compile your application once using the ant build target, and copy the following files to your web server:
    • The <Module Name>.nocache.js file generated by the GWT compiler
    • The <Module Name>.html HTML host page
    • The hosted.html and history.html files output during compilation.
    • The *.gwt.rpc file generated by the GWT compiler if your application uses java.io.Serializable to indicate serializability for objects transferred across GWT RPC.
    • If you are using image bundles, the clear.cache.gif file (and all other generated image files).

Be careful not to omit copying the files in Step #4: This is an action you'll only have to take once, but it is a necessary step. However, one important point to note is that you may need to replace the .gwt.rpc file if your application uses GWT RPC and the types that your application serializes across the wire implement the java.io.Serializable interface. If these types are changed, or new serializable types are added to your RPC calls, the GWT compiler will generate a new .gwt.rpc file. You will need to replace the old file deployed on your web server with the newly generated file. However, if your web server targets the GWT compiler's war output directory as the war directory for your application, you will not need to re-compile for these changes and hosted mode will take care of generating and correctly placing the *.gwt.rpc file. Also, if the hosted.html and history.html files weren't output during compilation, you can copy the files from the gwt-user.jar file in the /com/google/gwt/core/public package.

What are the options that can be passed to the HostedMode process?

There are many options you can pass to the hosted mode process to control how you want to start up the host ed mode browser. These options can differ slightly from version to version, but will generally include the options shown in the command-line help text below:

java -cp gwt-dev-<your platform here>.jar com.google.gwt.dev.HostedMode
Missing required argument 'module[s]'
Google Web Toolkit 1.7.0
HostedMode [-noserver] [-port port-number | "auto"] [-whitelist whitelist-string
] [-blacklist blacklist-string] [-logLevel level] [-gen dir] [-style style] [-ea
] [-server servletContainerLauncher] [-startupUrl url] [-war dir] [-extra dir] [
-workDir dir] [-localWorkers count] module[s]

where
  -noserver      Prevents the embedded web server from running
  -port          Specifies the TCP port for the embedded web server (defaults to 8888)
  -whitelist     Allows the user to browse URLs that match the specified regexes (comma or space separated)
  -blacklist     Prevents the user browsing URLs that match the specified regexes (comma or space separated)
  -logLevel      The level of logging detail: ERROR, WARN, INFO, TRACE, DEBUG, SPAM, or ALL
  -gen           The directory into which generated files will be written for review
  -style         Script output style: OBF[USCATED], PRETTY, or DETAILED (defaults to OBF)
  -ea            Debugging: causes the compiled output to check assert statements.
  -server        Specifies a different embedded web server to run (must implement ServletContainerLauncher)
  -startupUrl    Automatically launches the specified URL
  -war           The war directory to write output files into (defaults to war)
  -extra         The directory into which extra, non-deployed files will be written
  -workDir       The compiler work directory (must be writeable; defaults to a system temp dir)
  -localWorkers  Specifies the number of local workers to use when compiling permutations
and
  module[s]      Specifies the name(s) of the module(s) to host

Any time you want to look up the hosted mode options available for your version of GWT, you can simply invoke the HostedMode class from command-line as shown above and it will list out the options available along with their descriptions.

Compiling for Web Mode

What's with all the cache/nocache stuff and weird filenames?

During its bootstrap process, a Google Web Toolkit 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:

  • <Module Name>.nocache.js
  • <alphanumeric>.gwt.rpc

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

  1. The browser loads and processes the host HTML page.
  2. When the browser encounters the page's <script src="<Module Name>.nocache.js"> tag, it immediately downloads and executes the JavaScript code in the file.
  3. The .nocache.js file contains JavaScript code that resolves the Deferred Binding configurations (such as browser detection, for instance) and then uses a lookup table generated by the GWT Compiler to locate one of the .cache.html files to use.
  4. The JavaScript code in .nocache.js then creates a hidden <iframe>, inserts it to the host page's DOM, and loads the .cache.html file into that iframe.
  5. The .cache.html file contains the actual program logic of the 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.

The .cache.html Files

The "cache" files contain your application's logic. If you were to look inside a .nocache.html file, you would see that it is JavaScript code wrapped in a thin HTML wrapper. You might wonder why the GWT Compiler doesn't simply emit it as a JavaScript .js file. The reason for this is that certain browsers do not correctly handle compression of pure-JavaScript files in some circumstances. This would effectively mean that users unfortunate enough to be using such a browser would download the .js file uncompressed. Since the GWT mantra is no-compromise, high-performance AJAX code, the GWT Compiler wraps the JavaScript in an HTML file to wiggle around this browser quirk.

They are named according to the MD5 sum of their contents. This guarantees deterministic behavior by the GWT Compiler: if you recompile your application without changing code, the contents of the output will not change, and so the MD5 sums will remain the same. Conversely, if you do change your source code, the output JavaScript code will likewise change, and so the MD5 sums and thus the filenames will change.

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.js File

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.

The .gwt.rpc File

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.

Summary

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

How do I change the location of my cache/nocache HTML files?

The bootstrap process of a Google Web Toolkit application involves a <Module Name>.nocache.js file, and a number of .cache.html files. In the hosted 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 hosted target reads myapp, then the hosted 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

  • The application's host HTML file (that is, the file containing the <script> tag referencing the <module>.nocache.js file) may exist anywhere on a web site. There are no constraints on this URL.
  • The location of the <module`>.nocache.js file relative to the host HTML page is not significant; the .nocache.js file attempts to locate files relative to the URL from which it was loaded, not relative to the URL of the host HTML page.
  • The .cache.html and other files generated by the GWT compiler must be located at the same path as the .nocache.js file.

Example download sequence using the GWT bootstrap model

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:

  1. http://host.domain.tld/myApp/index.html
  2. http://host.domain.tld/myApp/MyApp.nocache.js
  3. http://host.domain.tld/myApp/CAFEBABE12345678DEADBEEF87654321.cache.html
For an example of the bootstrap sequence for a complete GWT application, check out the Developer Guide docs.

Relocating the files

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:

<script language="JavaScript" src="/gwt-files/MyApp.nocache.js"></script>

The example above would result in the following file download sequence:

  1. http://host.domain.tld/index.html
  2. http://host.domain.tld/gwt-files/MyApp.nocache.js
  3. http://host.domain.tld/gwt-files/CAFEBABE12345678DEADBEEF87654321.cache.html

Additional considerations

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() method. 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.getModuleBaseURL() + "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(). 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).

Why is my GWT-generated JavaScript gibberish?

By default, GWT obfuscates the JavaScript it produces. This is partly done to protect the intellectual property of the application you develop, but also because obfuscation reduces the size of the generated JavaScript files, making them faster to download and parse.

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:

  • OBF (for obfuscated), the default
  • PRETTY, which makes the output readable to a human
  • DETAILED, which improves on PRETTY with even more detail (such as very verbose variable names)

If you are curious about what GWT's generated JavaScript is doing, then you can use -style PRETTY. On the rare occasion where you are debugging GWT's output, then -style DETAILED might be helpful.

Can I speed up the GWT compiler?

If you are compiling a large application, you may find that compiling to web 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...

  1. Create a module called HelloFirefox that inherits Hello
  2. Use <set-property> in the HelloFirefox module that explicitly sets a value for

the user.agent client property. (See <define-property> in UserAgent.gwt.xml for the possible values.)

  1. Update your host html to refer to the HelloFirefox module rather than the Hello
module.
  1. Compile the HelloFirefox module instead of the Hello module.
  2. Look in the www/
    <modulename>
    
    / directory: there should be only one permutation compiled.

This example uses "gecko", which I tested on my older Firefox 1.0.7. First, the GWT module file:

<module>
    <inherits name="com.google.gwt.sample.hello.Hello"/>
    <set-property name="user.agent" value="gecko"/>
</module>

Next, the host HTML file:

<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <title>Hello</title>
  </head>
  <body bgcolor="white"> 
    <script type="text/javascript" language="javascript" src="com.google.gwt.sample.hello.HelloFirefox.nocache.js"></script>
  </body>
</html>

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.

To avoid keeping many nearly duplicate module files, the rename-to attribute on the <module> tag to create a working copy of the GWT application that is specific to the single-browser single-locale development mode. You can 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".

Is the war directory used by the GWT compiler as both an input and output directory to the compiler process?

In GWT 1.6, the compiler generates output in a directory structure following the Web Application Archive (WAR) standard layout. This is a newly introduced feature that 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.

Note that there is an open issue (Issue #3583) filed against the Google Plugin for Eclipse which does actually use the WAR directory as both input and output to the compilation process. This is expected to be fixed shortly.

For example, here is the build.xml file generated by the GWT webAppCreator script:

  <target name="gwtc" depends="javac" description="GWT compile to JavaScript">
    <java failonerror="true" fork="true" classname="com.google.gwt.dev.Compiler">
      <classpath>
        <pathelement location="src"/>
        <path refid="project.class.path"/>
      </classpath>
      <!-- add jvmarg -Xss16M or similar if you see a StackOverflowError -->
      <jvmarg value="-Xmx256M"/>
      <!-- Additional arguments like -style PRETTY or -logLevel DEBUG -->
      <arg value="com.google.gwt.sample.hello.Hello"/>
    </java>
  </target>

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:

  <target name="gwtc" depends="javac,copyresources" description="GWT compile to JavaScript">

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.

Does the new WAR output directory layout require me to use Java on the server-side?

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 has only been 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.

What are the options that can be passed to the Compiler process?

There are many options you can pass to the GWT compiler process to control how you want to compile your GWT application and where you want the output to be generated. These options can differ slightly from version to version, but will generally include the options shown in the command-line help text below:

java -cp gwt-dev-<your platform here>.jar com.google.gwt.dev.Compiler
Missing required argument 'module[s]'
Google Web Toolkit 1.7.0
Compiler [-logLevel level] [-treeLogger] [-workDir dir] [-gen dir] [-style style
] [-ea] [-validateOnly] [-localWorkers count] [-war dir] [-extra dir] module[s]

where
  -logLevel      The level of logging detail: ERROR, WARN, INFO, TRACE, DEBUG, SPAM, or ALL
  -treeLogger    Logs output in a graphical tree view
  -workDir       The compiler work directory (must be writeable; defaults to a system temp dir)
  -gen           The directory into which generated files will be written for review
  -style         Script output style: OBF[USCATED], PRETTY, or DETAILED (defaults to OBF)
  -ea            Debugging: causes the compiled output to check assert statements.
  -validateOnly  Validate all source code, but do not compile
  -localWorkers  Specifies the number of local workers to use when compiling permutations
  -war           The war directory to write output files into (defaults to war)
  -extra         The directory into which extra, non-deployed files will be written
and
  module[s]      Specifies the name(s) of the module(s) to compile

Any time you want to look up GWT compiler options available for your version of GWT, you can simply invoke the Compiler class from command-line as shown above and it will list out the options available along with their descriptions.