Calling GWT code from javascript

There are lots of snippets out there on the internet telling you how to run GWT code from javascript.  Here’s the canonical one.

I recently did a fair bit of this, calling GWT code from jquery.  Two things jumped out:

  • Make sure your jquery method is run in $(window).load(), not $(document).ready(). If you use the latter, your GWT code will not have executed and exported the javascript method to the window object. More on that.
  • I couldn’t find a list of valid java type signatures (even in the JVM book) for the longest time, but here they are, at long last.

Update, 2/26: I ran into some issues with using $window.load().  What you have to do instead is create a gwtonload function and call it from your gwt loader via jsni.  This ensures that GWT code is fully loaded, which $window.onload() does not.


GWT Code Splitting Process Tips

I have written before about GWT code splitting, a cool feature available in GWT.  While I am definitely no expert, it seems to be different that options offered by other, comparable web toolkits.  Just doing a quick survey (thanks, Ajaxian!), there seems to be a lot of code compilation happening.  Some of it is at deployment, pruning unused library code (like here, and here).  Some of it is aimed at making whatever javascript you write, better (like this and this).  There’s even tools aiming to document (in json) all javascript features supported by browsers, so that you can intelligently target user agents.

GWT code splitting is different from all of that.  It is developer determined split points in javascript code.  A developer says, essentially, all code after ‘this call’ should be downloaded and made accessible to the runtime when ‘this call’ is made.  More at the canonical reference; you should read this multiple times if you want to really understand code splitting.

As the document above mentions, “effective code splitting requires iteration”.  I’ve spent a fair bit of time in the last week doing some code splitting, and wanted to share my punch list (and build on my previous code splitting post).

First, understand the three major types of chunks your code will be split into.

  • Initial download
  • Leftover code
  • Exclusive fragments

The document above has a great diagram, which also includes other types of code which I have not run into.   The important thing to realize is that minimizing the initial download is important, but if any of the exclusive fragments are download, the leftover fragment will be downloaded.  Therefore, a better goal is to maximize the exclusive fragment size.

Here are places places to put split points, in order of preference

  • subsystems easily isolated (encryption library, etc).  Consider using the AsyncProxy, which is a great way to hide a subsystem
  • user actions (onclick events, etc).  Be aware of latency when toe code is downloaded and executed
  • when enabling spans are present

Use GWT.runAsync directly.  I tried to get all fancy with commands and abstracting it away, and didn’t have much success.  You can surround it with a timer, though, and that
may make sense when you are using an enabling span.

if (span is present) {
Timer t = new Timer() {

@Override
public void run() {
GWT.runAsync(new RunAsyncCallback() {
public void onFailure(Throwable caught) {
// handle error
}

public void onSuccess() {
foo();
}
});
}
};
t.schedule(150); // wait 150 ms before trying to download this code
}

You will spend a lot of time compiling, so only target a few browsers for compilation.  When I added the -compileReport option, the compile time for the main module went from 2 minutes to 8 minutes.  However, once you have the url for the compile report (something like /extras/modulename/soycReport/compile-report/SoycDashboard-0-index.html) you can actually see the results about a minute in.  At that point, you can stop the compile process.

Method call hunting will make you love your IDE java method search (control-H in eclipse–here’s a useful cheat sheet)

Watch out for constants and static methods.  In fact, I end up pulling out my constants to a class shared between GWT and my java server so that I can name spans like this
<div id="<%=Constants.SCROLL_ANCHOR_ID%>"></div> and be assured that GWT components will always be able to attach to those spans.

If module A is called by module B, C and D, avoid putting the GWT.runAsync calls in modules B, C and D.  This would force module A into the leftover code chunk, increases the number of split points, compilation time, and memory needs.  Instead, put the GWT.runAsync calls into module A, which pushes all that code into an exclusive chunk.  If you have a bunch of small splits points in your compile report, look at it carefully, especially if they are in the same class and see if you can push the split points back into the common code.

Code splitting failures (onFailure) should be dealt with the same way any remote access failure is dealt with in your application.  I haven’t found a more intelligent method than informing the user that the operation failed, however.

Set goals for splitting and try to avoid getting sucked in.  Because it is an iterative process, you can end up spending a lot of time with this.  Sometimes changes can have counter intuitive side effects, so make sure you track both total, initial and leftover code chunk sizes.

This post was based on a system with total obfuscated code size of approx 750kb, compiled using GWT 2.1.1.


Code splitting in cross domain GWT components

I just upgraded to GWT 2.1.  Lots of new features, though they are mostly aimed at building webapps (as opposed to enhancing websites).

The upgrade process was pretty painless.  A couple of notable changes (for my app):

  • <code>DeferredCommand</code> has been deprecated, and replaced with <code>Scheduler.get().scheduleDeferred</code>.  However, the API didn’t really change all that much, so this update is a simple search and replace (looks like the documentation has not yet been updated).
  • <code>HTTPRequest.getAsync</code>, which has been deprecated for years, finally disappeared.

The big win for me was code splitting when using the cross site (xs) linker.  This means that code served from one host can run on other domains and can include code splitting in the same manner as code that runs on the original host.

Why is this a big deal?  Two of our key widgets run on both our main host and subsidiary hosts.  These widgets are relatively complex, and it would be great for performance to split out that code so it wouldn’t be loaded on pages where it wasn’t shown.  This wasn’t really possible before GWT 2.1.  I’m still in the process of putting in the code split calls, but will let you know what the savings are when I’m done.

Update Jan 8, 2011: I was able to cut about 18% off the initial and leftover code download size.


How to get the GWT developer browser plugin

The Google Web Toolkit developer plugin, which integrates with a variety of browsers and lets you debug GWT code from within the Eclipse IDE, is astonishingly easy to get, but I haven’t found any great instructions, so I wrote this brief post.

You just need to start your IDE, start up any application in Development mode, and then visit the address the development mode server is running on in your browser (it will look something like this: “http://localhost:8080/host.html&gwt.codesvr=127.0.0.1:9997” if you are running off an external server–not sure what it looks like for folks using embedded jetty). It will send you to the ‘Missing Plugin’ page (or you can go there directly).

Some browsers are not supported (Safari on Windows is one I know of). The best list of supported browsers I was able to find was on the ‘Missing Plugin’ page; click the ‘plugins for other systems’ link.

BTW, this is different than the GWT plugin for Eclipse.


Avoid primitive object wrappers as return values for GWT javascript overlays

Just a warning, if you build javascript overlay types, you should make sure to only use primitives and strings as primary members of your overlay classes.  I’ve already written about overlay types once before, and here’s the GWT documentation.  If you dig a bit deeper in the GWT documentation, you see this quote:

JavaScript non-string objects always marshal as JavaScriptObject$

I was using a java.lang.Double as the return value for one of my overlay objects, and it was fine until I tried to do any math on it.  Nothing would seem to turn the value into a Double or a double, yet no exceptions were thrown.  After some sleuthing in web mode, it turned out that the value returned when I was trying to parse it was NaN, even though when I output it to the screen, the value looked like a double.  I guess it was being treated as a JavaScriptObject$.

Easily enough fixed, just make sure that you don’t use any objects wrappers of primitives in an overlay type.


Namespace Collisions, NS_ERROR_XPC_CANT_CONVERT_WN_TO_FUN and GWT

So, the abstraction layer provided by GWT just leaked–well, more of a flood than a leak.

I am working on a site that is pulling in an html fragment which included some javascript code via an XML HttpRequest.  This new code will make paging the results of a search quicker, hopefully leading to happier users.  For reasons too obscure to go into, I was creating a variable named ‘r1’ which I was then adding to the DOM.  The name was completely arbitrary, and was due to laziness (hey, why type 3 characters when you can type 2?).

Fast forward to today, when we’re getting ready to launch the update.  Occasionally, but not often, code that GWT was executing was throwing an exception.  One of the other developers found it because some functionality was disabled.  Here’s what that exception looked like:

exception: (NS_ERROR_XPC_CANT_CONVERT_WN_TO_FUN): Cannot convert WrappedNative to function
QueryInterface: function QueryInterface() {
[native code]
}
result: 2153185293
filename: http://stageserver/gwt/2B17113CD349EDFD95DC846F38AB0857.cache.html
lineNumber: 4268
columnNumber: 0
inner: null
data: null
initialize: function initialize() {
[native code]
}

Now, usually, the first thing I do when I see an exception is to recompile the GWT with -style DETAILED instead of -style OBF and see where the error occurs.  However, when I did that, I didn’t see the error message any more.

OK, I added more debugging.  If I added a certain number of alert statements, the error message was nowhere to be found.  OK, go back to the previous code.  Try different pages, different browsers.  Sometimes the exception reared its head, other times it didn’t.  It appeared on some browsers and not others. Sprinkled alerts throughout the code, found the exact line where the exception was being thrown.  All that line did was create a click listener.

Nothing really clear on google; however, this post was useful in pointing to the error message being a collision between a function name and a DOM element.  Searching the GWT google group was not helpful.   I tried using the Firebug debugger, but on obfuscated source, it was not helpful to me.

These kind of bugs make me want to tear out my hair.  Hardly reproducible bugs are no fun. However, I finally found the issue (if I hadn’t, I’d still be working and wouldn’t be posting, that’s for sure).

How I finally solved it:  I was getting a line number.  I finally edited the generated GWT .cache.html file and added some newlines.  This would let me find out exactly which function was really causing the issue.

And, lo and behold, the problematic function was named ‘r1’.

Changing the name of the DOM element fixed this issue. Beware short named javascript DOM elements when working with GWT.

Hope this helps you.


GWT Marketplace

Two years ago, I surveyed the state of GWT widgets.  It was pretty fragmented and a bit confusing.  While I haven’t been paying very close attention, I don’t think things have changed much.

I was browsing around the GWT google group, and found this interesting announcement.

I’m a huge fan of GWT and the only problem I have with it is not really a problem with GWT but with the fact that there isn’t a centralized place for registering component and associated tools AFAIK.  I have created an application to do this which is available at http://gwtmarketplace.appspot.com/

I visited the marketplace and while it is currently in its infancy, it could be very useful. If you have GWT code that you want to share with the world, consider registering it. I added gwt-crypto, which I help maintain.


More on code splitting and GWT

Code splitting is one of the features of GWT that make it worth your while.  See, using GWT is really a choice–do you want to use one of the lightweight javascript libraries like jquery, with all the agility that implies, or do you want to use GWT which lets you leverage all kinds of java tools and optimizations, but saddles you with a compile cycle?

I’ve talked before about the situations that I think are good fits for GWT.  I just re-read that post and don’t feel that things have changed too much in the past 3 years, though I might argue with point 4 of that post.  Code splitting is an optimization that would be hard to do with a more normal javascript library (dojo has something like it, but it looks like you are responsible for maintaining dependencies).

I talked before about code splitting, and how it is a great fit for the widget based html enhancing GWT development that I’ve done a lot of recently.  I wanted to talk a bit more about my process for finding code to split.

With code splitting, the main goal is “never have the user download javascript that isn’t used”.

The first thing to do is run your GWT compile with the -compileReport option, as outlined here. This will show you your module code, and therefore let you focus your effort where it makes sense.

The second thing to do is to find code dependencies.  The compile report shows you that in a text format if you navigate all the way down to the class level in a class that is downloaded in the inital fragment via the “see why” link.  I had a hard time understanding those dependency lists, so I went looking for a tool to help.  After trying a number of open source dependency analyzers, I stumbled on the Class Dependency Analyzer (CDA) which is free as in beer, not as in speech.  The key difference between this tool and others was its included dependency graphs.  You should set CDA up to ignore all the google code, as well as any third party tools you have.  More documentation on CDA here.  (This is another example of leveraging java’s tool set.)

Using CDA, you can see which packages (since modules are grouped in a java package) have dependencies on others.  Packages that don’t have dependencies on any of your other packages are great candidates for code splitting, as well as packages that depend on other packages that are code split.  However, if your packages depend on utility classes, especially those that share business logic between client and server side code, that’s OK.  (This exercise can also help in general code quality.)

Now you have a number of candidate modules.  The next thing to do is dive into the code and see if these modules execute on every page.  If they do, then doing code splitting is not a win.  All you’ve done is forced GWT to make an extra network call.  If, on the other hand, this code only executes when someone clicks a button or takes some other action, then you have a great candidate for code splitting.  And if the module only executes on certain pages (perhaps using a DOM element to signal whether it should execute or not), you have a good candidate–because with splitting that code will never be download on pages where it is not used.

Now, add the following code around the candidates:

GWT.runAsync(new RunAsyncCallback() {
public void onFailure(Throwable caught) {
// handle error
}

public void onSuccess() {
// do something
}
}

I actually added this code block to my eclipse templates ( more on templates here) so it is super easy to set up a split point.  Note that I haven’t found a generic good action to take on failure.  For most widgets providing enhanced functionality, a safe fallback might be to just let the HTML execute.  A custom message display might be ignored, and using Window.alert can confuse your users (and lock up a browser for a time if all of your code or the network suddenly becomes unavailable).

The next step is to run the compile report again and see if the GWT compiler agrees with you that your candidate code is not reachable by any other path.  If it does, you should see split points show up underneath the permutations menu.  (BTW, the -compileReport flag easily doubles or triples the time it takes to compile GWT–I’d recommend focusing on one user-agent and doing other things to speed up your compile, as outlined here.)  You can also test this by just compiling your GWT without the -compileReport switch and looking under the deferredjs directory; it is quicker but doesn’t help you determine which modules are being downloaded.  Firebug also lets you see the files downloaded on demand.

I was able to decrease the initial download size of a project I’m working on by 20%.

I’ve mentioned the caveats before but they are worth mentioning again.

  • The XS linker is not supported, so if any of your XS modules depend on a module which has code splitting, you’ll find out when your GWT does not compile.  However, there is hope–code splitting support for the XS linker is apparently coming with GWT 2.1.  If you need this functionality, vote for the bug.  There are some work arounds in the meantime, but they involve a fair bit of hoop jumping so I’m going to avoid documenting them.
  • Events that happen before code is asynchronously downloaded are not propagated to that code.

Given the second issue, it’s important to test your code and make sure that the behavior is unchanged.  That’s the final step.

I hope this was a useful tour of the GWT code splitting process.


When is a Boolean != to a boolean

Among other times, when you’re passing it into a JSNI method in GWT.  From the docs, only a java boolean is translated into “JavaScript boolean value, as in var b = true;”  A Boolean is, like any other Java object, an “opaque value accessible through special syntax”.


Using JSP as a templating language for GWT

I wanted to share a solution to a problem a client of mine had–needing the same (or very similar) content in two places–in a lightbox, managed by GWT, and in an HTML page.  The content itself had GWT widgets inside it (that would need to be functional in both places).

The solution was to expose the HTML content as a JSONP file for GWT consumption (and just have the HTML displayed for the HTML page).  To do this,

  • we build the HTML page (in this case, using JSTL and JSP, but any other HTML view technology would work).
  • then we build code that retrieves the page (I used HttpClient)
  • and encodes the entire HTML content as an attribute of a json object (I used json-simple)
  • and exposes it to the world via a URL

Now that we have the content as JSON encoded HTML, we need to consume it:

  • first, create a JSONP consumer, as outlined here
  • then, when you get the content, pull it into an HTMLPanel, not just a HTML widget
  • create new instances of your GWT widgets and attach them to your known span ids using the HTMLPanel.add() method.
  • if your content depends on external css files, you’ll need to add and remove them via JSNI when the lightbox is shown (if you can’t integrate the CSS into the existing site)
  • if your lightbox and html content differ slightly, you can hide or show spans via your server side presentation layer to configure your in lightbox widgets

Benefits

  • One location for display–one place to make changes
  • No layout in GWT–everything happens in HTML
  • Cross domain–since the content is exposed via JSONP, it can be consumed by javascript on any domain.

Detriments

  • Security–you’re exposing yourself to some possible security issues, though since you control both the endpoints, they shouldn’t be too bad.  Read this excellent document carefully to understand the implications.
  • Complexity–lots of moving pieces
  • Caching–JSONP calls are cached by the browser, and a control refresh doesn’t seem to refresh them.  I end up clearing my cache a lot when debugging.
  • Two calls to the server for every lightbox shown.
  • Not sure if it would work in developer mode–possibly with an external server.  Haven’t tried this.

I haven’t played around with any of the GWT templating solutions, but I don’t believe they would work in this case, because of the need for a plain, crawlable HTML page.



© Moore Consulting, 2003-2017 +