Curiously, these browser technologies have been available for many years, yet it has taken until now for mainstream developers to cobble them together to create compellingly interactive Web applications. Why? The opinion of the Google Web Toolkit teama perspective that can, of course, be endlessly debatedis that the primary obstacle is literally the implementation details. It is simply too difficult to code them all to work together in a way that provides quick and reliable performance on the wide range of browsers available.
GWT began life as a prototype that Google software engineer Joel Webber and I produced as a way to address what might best be described as the over-constrained problem of Web development. Thanks largely to the success of Google Maps and Gmail, several points had simultaneously become clear to us:
- End users really liked and wanted browser-based applications.
- Rich client-side interactivity (for example, Maps and Gmail) made such applications much more responsive and usable than typical Web 1.0 page-at-a-time applications and thus much more compelling.
The source for the two examples looks nearly identical, except for minor syntax differences, the use of
@Override (which is useful for helping to prevent bugs), and the presence of explicit type names sprinkled on fields, methods, and local variables.
Because of the extra type information, the GWT compiler is able to perform some optimizations. The unobfuscated version of the GWT compiler output looks approximately like this:
Note that in  and , a cascade of optimizations was made.
First, the compiler inlined both calls to the
displayArea() method. This proved helpful because it removed the need to generate code for that method. Indeed,
displayArea() is completely absent from the compiled script, resulting in a minor size reduction. Even better, the inlined code is amenable to being further optimized in a usage-specific context where more information is available to the optimizer.
Next, the optimizer noticed that the types of
shape2 could be "tightened" to types more specific than their original declaration. In other words, although
shape1 was declared to be a Shape, the compiler saw that it was actually a Circle. Similarly, the type of
shape2 was tightened to Square. Consequently, the calls to
getArea() in  and  were made more specific. The former became a call to Circle's
getArea(), and the latter became a call to Square's
getArea(). Thus, all the method calls were statically bound, and all polymorphism was removed.
Finally, with all polymorphism removed, the optimizer inlined Circle's
getArea() into  and Square's
getArea() into . Both
getArea() methods are absent from the compiled script, having been inlined away.
Math. PI is a compile-time constant and was also trivially inlined into .
The benefit of all these optimizations is speed. The script produced by the GWT compiler executes more quickly because it eliminates multiple levels of function calls.
Bringing Together Two Worlds
Of course, the creation of an environment that allows developers to build browser-based applications in Java addresses only one part of the development cycle. Like most developers, we do not produce perfect code, so we knew we would also have to address the issues involved in debugging GWT programs.
Upon first hearing about GWT, people often assume you use it in the following way:
- Write Java source.
The secret to making hosted mode an effective debugging environment is that it does not merely simulate the behavior of a browser while debugging in Java. Hosted mode directly combines true Java debugging with a real browser UI and event system. Hosted mode is conceptually simple, and it executes in a single JVM (Java Virtual Machine) process:
- Launch an instance of an actual browser, embedded in-process, that can be controlled by Java code via JNI (Java Native Interface). We call this the hosted browser.
- Create a CCL (compiling class loader) to load the GWT module's entry-point classes.
- Run the bytecode of the entry-point class, which will in turn request other classes be loaded by the CCL, which repeats the process from Step 3.
GWT thus manages to combine the benefits of a traditional optimizing compiler with the quick development turn-around of dynamic languages. Although the compilation technology may appear complex, it is actually fairly standard fare for optimizing compilers. The real technical problems we encountered along the way revolved around our efforts to create UI libraries to simultaneously account for browser-specific quirks without compromising size or speed. In other words, we needed to supply many different implementations of UI functionalityversion A for Firefox, version B for Safari, and so forthwithout burdening the compiled application with the union of all the variations, thereby forcing each browser to download at least some amount of irrelevant code. Our solution is a unique mechanism we dubbed deferred binding, which arranges for the GWT compiler to produce not one out put script, but an arbitrary number of them, each optimized for a particular set of circumstances.
Each compiled output is a combination of many different implementation choices, such that each script has exactly (and only) the amount of code it requires. It's worth mentioning that in addition to dealing with browser variations, deferred binding can specialize compilations along other axes as well. For example, deferred binding is used to create per-locale specializations (for example, why should a French user have to download strings localized for English, or vice versa?). In fact, deferred binding is completely open ended, so developers can add axes of specialization based on their needs.
This approach does create a large number of compiled scripts, but we reasoned it was a welcome trade-off: you end up spending cheap server disk space on many optimized scripts, and, as a result, applications download and run more quickly, making end users happier.
In any event, our experience in developing GWT has thoroughly convinced us that there's no need to give in to the typical constraints of Web development. That is, with a bit of creativity and some dedicated effort, we now know it is indeed possible to retain the richness of more familiar development environments without compromising the experience application users are ultimately to enjoy.
Case Study: Making the Move to AJAX
Coding Smart: People vs. Tools
Debugging AJAX in Production
©2009 ACM 0001-0782/09/0900 $10.00
Permission to make digital or hard copies of all or part of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice and the full citation on the first page. To copy otherwise, to republish, to post on servers or to redistribute to lists, requires prior specific permission and/or a fee.
The Digital Library is published by the Association for Computing Machinery. Copyright © 2009 ACM, Inc.