We're happy — no, ecstatic — to announce that GWT 1.5 is now officially released and available for download.
Download GWT 1.5
GWT 1.5 delivers what we think are an impressive number of improvements, about four hundred issues if you're counting. We're also happy that one of those is issue 168, our most-requested feature, Support for Java 5.
Support for Java 5
We've blogged about several of the new features already. Now that it's official, let's recap and expand the list a bit...
@gwt.typeArgs
StringBuilder
TreeMap
LinkedHashMap
-ea
assert
just feel faster.
feels faster
Tree
MenuBar
TabPanel
Those are some highlights. The (new) GWT Developer's Guide has a more detailed explanation of GWT 1.5 changes, including notes about a few breaking changes you'll want to be aware of.
For further information or for help getting started with GWT, you may find the follow links helpful:
We really hope that you'll find that GWT 1.5 helps you build the most sophisticated web apps you can envision. And when you build the next big thing, please share your success stories in the GWT developer forum.
We're happy to say that the first Release Candidates for the Google API Libraries for Google Web Toolkit are now ready to be taken for a test drive.
The project is a collection of libraries that provide Java language bindings and API specific plumbing for some Google JavaScript APIs. The goal is to make it easy for developers to use these JavaScript APIs with GWT. Libraries available at this time include a new version of Gears, as well as new libraries for Gadgets and the Google AJAX Search API.
Gears 1.1 Library (Release Candidate) A new version of the Gears library is available. In addition to the earlier version's support for the Gears LocalServer, Database, and WorkerPool, 1.1 adds integrated support for offline applications and updated sample applications. The bindings have also been refactored to use GWT 1.5 JavaScript overlay types and a new package hierarchy.
Gadgets 1.0 Library (Release Candidate) The Gadgets library simplifies gadget development with GWT by automatically generating a Gadget specification from Java source and inserting a selection script in the specification much like a regular GWT project. After compiling your gadget with GWT, all files are in place to publish your gadget. This version currently supports the legacy Gadgets API based on the _IG_... namespace.
Google AJAX Search 1.0 Library (Release Candidate) The Google AJAX Search API lets you put Google Search in your web pages, including Web, Local, and Multimedia searches. This library allows you to access the API from Java code compiled with the GWT compiler without having to write additional JavaScript code.
If you've been following the early milestone builds, you may also be aware that a Google Maps API Library for GWT is in the works. Stay tuned for a release candidate for that library.
With this set of release candidates, each library is now distributed separately so that you can download only the specific library you are interested in.
We encourage you to try these release candidates out and give us feedback, either through the issue tracker on code.google.com, or through the Google-Web-Toolkit or Google-Web-Toolkit-Contributors group.
The second release candidate of GWT 1.5 is available for download now.
Thanks to everyone who started using GWT 1.5 RC1 and shared feedback. With your help, we're very near the end of the big GWT 1.5 development cycle.
If you haven't already, now would be a great time to start upgrading your project to take advantage of all the new features and great performance gains in GWT 1.5.
Enjoy!
Suppose you're happily using JSNI to call bits of handwritten JavaScript from within your GWT module. It works well, but JSNI only works at the level of individual methods. Some integration scenarios require you to more deeply intertwine JavaScript and Java objects — DOM and JSON programming are two good examples — and so what we really want is a way to interact directly with JavaScript objects from our Java source code. In other words, we want JavaScript objects that look like Java objects when we're coding.
GWT 1.5 introduces JavaScript overlay types to make it easy to integrate entire families of JavaScript objects into your GWT project. There are many benefits of this technique, including the ability to use your Java IDE's code completion and refactoring capabilities even as you're working with untyped JavaScript objects.
Overlay types are easiest to understand with examples. Suppose we want to access an array of JSON objects representing a set of "customer" entities. The JavaScript structure might look like this:
var jsonData = [ { "FirstName" : "Jimmy", "LastName" : "Webber" }, { "FirstName" : "Alan", "LastName" : "Dayal" }, { "FirstName" : "Keanu", "LastName" : "Spoon" }, { "FirstName" : "Emily", "LastName" : "Rudnick" } ];
To superimpose a Java type onto the above structure, you start by subclassing JavaScriptObject, a marker type that GWT uses to denote JavaScript objects. Let's go ahead and add some getters, too.
JavaScriptObject
// An overlay type class Customer extends JavaScriptObject { // Overlay types always have protected, zero-arg ctors protected Customer() { } // Typically, methods on overlay types are JSNI public final native String getFirstName() /*-{ return this.FirstName; }-*/; public final native String getLastName() /*-{ return this.LastName; }-*/; // Note, though, that methods aren't required to be JSNI public final String getFullName() { return getFirstName() + " " + getLastName(); } }
GWT will now understand that any instance of Customer is actually a true JavaScript object that comes from outside your GWT module. This has useful implications. For example, notice the this reference inside getFirstName() and getLastName(). That this is truly the identity of the JavaScript object, so you interact with it exactly as it exists in JavaScript. In this example, we can directly access the JSON fields we know exist, this.FirstName and this.LastName.
Customer
this
getFirstName()
getLastName()
this.FirstName
this.LastName
So, how do you actually get a JavaScript object on which to overlay a Java type? You can't construct it by writing new Customer() because the whole point is to overlay a Java type onto an already existing JavaScript object. Thus, we have to get such an object from the wild using JSNI:
new Customer()
class MyModuleEntryPoint implements EntryPoint { public void onModuleLoad() { Customer c = getFirstCustomer(); // Yay! Now I have a JS object that appears to be a Customer Window.alert("Hello, " + c.getFirstName()); } // Use JSNI to grab the JSON object we care about // The JSON object gets its Java type implicitly // based on the method's return type private native Customer getFirstCustomer() /*-{ // Get a reference to the first customer in the JSON array from earlier return $wnd.jsonData[0]; }-*/; }
Let's clarify what we've done here. We've taken a plain-old-JSON-object (POJSONO, anyone? no?) and created a normal-looking Java type that can be used to interact with it within your GWT code. You get code completion, refactoring, and compile-time checking as you would with any Java code. Yet, you have the flexibility of interacting with arbitrary JavaScript objects, which makes things like accessing JSON services via RequestBuilder a breeze.
A quick digression for compiler geeks. Another neat thing about overlay types is that you can augment the Java type without disturbing the underlying JavaScript object. In the example above, notice that we added the getFullName() method. It's purely Java code — it doesn't exist on the underlying JavaScript object — and yet the method is written in terms of the underlying JavaScript object. In other words, the Java view of the JavaScript object can be richer in functionality than the JavaScript view of the same object but without having to modify the underlying JS object, neither the instance nor its prototype.
getFullName()
prototype
(This is still part of the digression.) This cool wackiness of adding new methods to overlay types is possible because the rules for overlay types by design disallow polymorphic calls; all methods must be final and/or private. Consequently, every method on an overlay type is statically resolvable by the compiler, so there is never a need for dynamic dispatch at runtime. That's why we don't have to muck about with an object's function pointers; the compiler can generate a direct call to the method as if it were a global function, external to the object itself. It's easy to see that a direct function call is faster than an indirect one. Better still, since calls to methods on overlay types can be statically resolved, they are all candidates for automatic inlining, which is a Very Good Thing when you're fighting for performance in a scripting language. Below we'll revisit this to show you just how much this regimen pays off.
final
private
We glossed over something in the example above. The method getFirstCustomer() is pretty unrealistic. You're certainly going to want to be able to access the entire array of customers. Thus, we need an overlay type representing the JavaScript array itself. Fortunately, that's easy:
getFirstCustomer()
// w00t! Generics work just fine with overlay types class JsArray<E extends JavaScriptObject> extends JavaScriptObject { protected JsArray() { } public final native int length() /*-{ return this.length; }-*/; public final native E get(int i) /*-{ return this[i]; }-*/; }
Now we can write more interesting code:
class MyModuleEntryPoint implements EntryPoint { public void onModuleLoad() { JsArray<Customer> cs = getCustomers(); for (int i = 0, n = cs.length(); i < n; ++i) { Window.alert("Hello, " + cs.get(i).getFullName()); } } // Return the whole JSON array, as is private final native JsArray<Customer> getCustomers() /*-{ return $wnd.jsonData; }-*/; }
This is nice clean code, especially considering the flexibility of the plumbing it's built upon. As hinted at earlier, the compiler can do pretty fancy stuff to make this quite efficient. Take a look at the unobfuscated compiled output for the onModuleLoad() method:
onModuleLoad()
function $onModuleLoad(){ var cs, i, n; cs = $wnd.jsonData; for (i = 0, n = cs.length; i < n; ++i) { $wnd.alert('Hello, ' + (cs[i].FirstName + ' ' + cs[i].LastName)); } }
This is pretty darn optimized. Even the overhead of the getFullName() method went away. In fact, all of the Java method calls went away. When we say that "GWT gives you affordable abstractions," this is the kind of thing we're talking about. Not only does inlined code run significantly faster, we no longer had to include the function definitions themselves, thus shrinking the script a litte, too. (To be fair, though, inlining can also easily increase script size, so we're careful to strike a balance between size and speed.) It's pretty fun to look back at the original Java source above and try to reason about the sequence of optimizations the compiler had to perform to end up here.
Of course, we can't resist showing you the corresponding obfuscated code:
function B(){var a,b,c;a=$wnd.jsonData;for(b=0,c=a.length;b<c;++b){ $wnd.alert(l+(a[b].FirstName+m+a[b].LastName))}}
Notice in this version that the only bits that aren't obfuscated are the identifiers that originated in JavaScript, such as FirstName, LastName, jsonData, etc. That's why, although GWT strives to make it easy to do lots of JavaScript interop, we try hard to persuade people to write as much of their code as possible as pure Java source instead of mixing with JavaScript. Hopefully now when you hear us say that, you'll understand that we aren't bashing JavaScript — it's just that we can't optimize it as much, which makes us sad.
FirstName
LastName
jsonData
Overlay types are a key new feature in GWT 1.5. At its simplest, the technique makes direct interop with JavaScript libraries much easier. Hopefully after this post you could imagine how to almost directly port any JavaScript library into GWT as a set of Java types, thus allowing the use of a Java IDE for productive development and debugging without impacting size or speed due to any sort of GWT overhead. At the same time, overlay types serve as a powerful abstraction tool for delivering more elegant low-level APIs such as the the new GWT DOM package.
For more information...
RequestBuilder