GWTBridge Not Found in GWT2.5

Just updated the GWT SDK and ended up with a broken app:

java.lang.NoClassDefFoundError: com/google/gwt/core/client/GWTBridge
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:169)
	at com.google.appengine.tools.development.agent.runtime.RuntimeHelper.checkRestricted(RuntimeHelper.java:70)
	at com.google.appengine.tools.development.agent.runtime.Runtime.checkRestricted(Runtime.java:64)

After some searching/experimenting and a cup of coffee it finally occurred to me: the package name says client! So all the time I have been using a client-package class in my server-side code. Kinda surprising that it did work nicely all the while.

Solution: replace all com.google.gwt.core.client.GWT with com.google.gwt.core.shared.GWT in shared and server-side code.

Using GWT’s DateTimeFormat in Server-Side Code

I was working on some utility class to format dates. As the formatting is the same on server and client the same class should be used on both, server and client. Within the GWT framework there is the DateTimeFormat class which seems to be supposed to do exactly that.

But despite being in the shared package (com.google.gwt.i18n.shared.DateTimeFormat) using it in the server-side code causes

java.lang.UnsupportedOperationException: ERROR: GWT.create() is only usable in client code!  It cannot be called, for example, from server code. If you are running a unit test, check that your test case extends GWTTestCase and that GWT.create() is not called from within an initializer or constructor.

Having a look into the code of the DateTimeFormat class (which is part of the shared package of the GWT framework, thus can be used on server and client) reveals there is an import of com.google.gwt.i18n.client.LocaleInfo. But this class is part of the client package – thus, it can not be used in the server-side code. It’s unclear to me why this was done like that because it simply can not work by definition…

Going down a bit further in the code of the DateTimeFormat class shows that the client package class LocaleInfo is used only once like this:

private static DateTimeFormatInfo getDefaultDateTimeFormatInfo() {
  // MUSTFIX(jat): implement
  return LocaleInfo.getCurrentLocale().getDateTimeFormatInfo();
}

The line is marked as “MUSTFIX” but for some reason it has not been fixed yet.
There is a way to fix this issue that worked for me:

  • Copy the content of DateTimeFormat to a new file in your own code
  • Remove the import of LocaleInfo
  • Changing the following method (starting in line 656) like this:
private static DateTimeFormatInfo getDefaultDateTimeFormatInfo() {
  return new DefaultDateTimeFormatInfo();
}
  • And use this newly created class from now on in all your code.

The fix does not seem to cause any major harm, but as John A. Tamplin (cf. his comment below) clearly pointed out, applying this fix will render all dates using the default locale instead of using the user’s locale. Thus, this fix should be considered a hack rather than a patch – but it does the trick until the bug has been fixed officially.

The hack can be applied quickly – or simply download the fixed class here.

p.s. Unfortunately, it is not possible to just overwrite the method in a derived class because it’s a static method and private anyway.
p.p.s. As suggested in the comments, you might also initialize the DateTimeFormat with a new DefaultDateTimeFormatInfo() as the second paramenter. (Please note that I did not verify this suggestion) In general, both ways of fixing this issue will cause that the date and time to be formated using the default locale rather than the user’s current locale, unfortunately.

How to Use JQuery in GWT

After adding the JQuery script to your project HTML file’s header section

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>

You will be able to use JQuery in native (JSNI) methods by prepending $wnd., e.g.:

private native void someMethod() /*-{
	$wnd.$(function() {
		$wnd.$('#somediv').doSomething();
	});
}-*/;

Without $wnd. you will end up with following error: com.google.gwt.core.client.JavaScriptException: (ReferenceError): $ is not defined

JUnit-Testing and GAE APIs

Some issues I encountered when testing a new Java library for loading multiple URLs in parallel on the Google Apps Engine (GAE) (more about that library in another post).

Here are some of the typical errors you might encounter:

Missing timeout class

java.lang.NoSuchMethodError: org.mortbay.thread.Timeout

Context menu on project: Properties -> Build Path -> Order and Export: move GWT SDK *above* App Engine SDK (cf. here)

Compilation unit was not seen

com.google.gwt.junit.JUnitFatalLaunchException: The test class 'com.test.client.MyTest' was not found in module 'com.text.Module'; no compilation unit for that type was seen

  • The test class needs to be within a package that is configured in the module file (*.gwt.xml). You should create a new source folder (Context menu on project -> New -> Source Folder) and create the whole package structure you use within your project up to client, e.g. com.company.client, and put your GWT tests in it. This way you make sure that the tests are not going to be deployed to GAE later on.
  • If you are testing client-side code, your test class needs implement GWTUnit *and* be run as GWTUnitTest *not* as JUnitTest 😉

API package not found

java.util.concurrent.ExecutionException: com.google.apphosting.api.ApiProxy$CallNotFoundException: The API package 'urlfetch' or call 'Fetch()' was not found.

The GAE environment has not been initialized.

  • Set up the required libraries for testing:
    • Context menu on project -> Properties -> Build Path -> Libraries -> Add Variable -> Configure Variables -> New…: Set "SDK_ROOT" as name and search you disk for "appengine-api-stubs.jar" and copy the part before "/lib/impl" into the text box named "Path"
    • Select "SDK_ROOT" from the previous dialog, click "Extend…", unfold lib and impl and select "…labs.jar", "…stubs.jar", and "…api.jar"; unfold "lib/testing" and select "…testing.jar" — done, whew.
  • Add following lines to your test class:
    private final LocalServiceTestHelper helper = new LocalServiceTestHelper(new LocalURLFetchServiceTestConfig());
    @Before public void setUp() { helper.setUp(); }
    @After public void tearDown() { helper.tearDown(); }
  • Have a look in com.google.appengine.tools.development.testing to see all the services/APIs available for testing and replace LocalURLFetchServiceTestConfig with the one you need.

I tried to keep it as brief as possible, for more details have a look at this page.

Improving Canvas Performance

1. Timeout instead of Scheduler

Surprisingly, using com.google.gwt.user.client.Timer seems much faster then relying on com.google.gwt.core.client.Scheduler. I did not yet evaluate the differences in detail but the lower CPU workload speaks for itself.

2. AnimationScheduler

I am not really sure if this helps a lot, but you will find a lot of online documentation explaining that you should use this:
com.google.gwt.animation.client.AnimationScheduler.get(). requestAnimationFrame(callback, element);. The element parameter is optional but said to improve performance as the browser can decide when to render optimally.
So whenever your timer kicks in, and you are ready to render the results, use the AnimationScheduler instead of calling your rendering routines right away. It will only take very few milliseconds (depending on the users screen frame rate—which is 60 Hz or more usually) for the callback to return to your code.

3. Caching

This parts requires much more effort and depends on your software architecture and requirements. The basic idea is not to redraw things that did not change. To do so we can draw each item on a hidden canvas once and then reuse this rendering during every drawing cycle.
As the process is a bit more complicated, I will dedicate it a separate post—comming soon!

4. Save on effects

Yes, effects is what the canvas is all about, but something like a shadow can cost quite some CPU power. So if you run into problems check if some of the effects can be achieved cheaper or even be removed.

Multiple Projects and GWT

When working on several large scale projects (in Eclipse), it’s convenient and of course more efficient to share and reuse code via common libraries. While those are in an early stage they need to be changed a lot and therefore it’s handy to link projects in instead of creating new jars each time the library has been updated.
Unfortunately, this standard approach for Java development in Eclipse does not work that straight forward as with plain old Java projects, it requires three steps in total:

  1. Link the library project to all relevant projects ("Project Preferences" -> "Java Build Path" -> "Projects" -> "Add…")
  2. Then, add the client-side code of the library (by adding it as a module.) Therefore, edit the gwt.xml of your application and add for example <inherits name="net.svenbuschbeck.gwt.lib.SuperLib "/> where SuperLib is the file name of the gwt.xml file in you library project and before that is the package it lies in.
  3. Add the code to the project by linking a source folder. Unfortunately, this is required if you do not want to write an Ant script to compile your application. (If you prefer Ant check this out) I don’t like the idea of using such a script because if you forget to run it each time you make changes, you will end up in confusion—let’s go for the convenient, automatic way then.
    1. Add a folder to your application project; open the "advanced" section in the folder creation dialog, select "Link to alternate location" and pick the source folder (usually "src") of your library project. (Hint: if you work within a team using a versioning system, you can create a variable for that folder and use this instead. This way, each of your colleagues can put the library project in a different folder and accommodate for that by adjusting the variable 🙂 )
    2. Right click the folder, "Build Path" -> "Use as Source Folder". Done.

Surprisingly, the GWT plugin for Eclipse does not honor the project linking, thus all the references need to be made explicit or you will end up with lots of the following: ClassNotFoundException.

“An invalid or illegal string was specified” Exception in GWT

While working with canvas (drawing stuff on it) in GWT, suddenly and in a seemingly unpredictable manner I got following error message now and then from within the GWT framework code:

com.google.gwt.core.client.JavaScriptException: (NS_ERROR_DOM_SYNTAX_ERR): An invalid or illegal string was specified;

Again, GWT tricked me into thinking I am writing Java code and made me forget about that it is going to be compiled into Javascript. And because of the latter, a division by zero does not throw an DevisionByZeroException, no, it returns NaN even for native data types (there is no differentiation between double and Double in Javascript – there is only the object-version of double, which can be of value Double.NaN).

But also GWT was not prepared to handle Double.NaN. When calling canvas.getContext().drawImage(image,x,y) and one of x and y or both were Double.NaN I got the error message shown above. If you got the same… you know what to do now: check all devisions in your code for potential devisions by zero!!

Sorting Lists in GWT

Quick one:
Lists.sort(list, comparator) is not implemented in the GAE JVM.
But, as a replacement/alternative, Collections.sort(list, comparator) is.

How to Execute Code When the GWT Application Is Going Down

My goal was to store the UI state of my application just before it gets terminated to be able to restore it next time the way the user left it the other day.

I tried to add an addAttachHandler to the RootPanel to get informed about the root panel getting detached from the DOM so that I can finalize my application. Surprisingly, that does not work in Chrome (tested Chrome and Firefox only).

But besides that this sounds like a bug to me, I found the “proper” way of doing things before the application ends:

Window.addWindowClosingHandler(new Window.ClosingHandler() {
	@Override public void onWindowClosing(ClosingEvent event) { ... } 
});

In the end, I think something like Document.addUnloadHandler would be more suggestive… closing the window or reloading a page is both exiting the application by unloading the DOM – not closing the window.

Disable an Anchor in GWT

Unexpectedly, calling setEnabled(false) does not prevent a link/anchor from being clicked. That means, the click events still get triggered.
The reason is more or less a bug in GWT as it updates the list of events that are going to be triggered only at the moment when it gets attached to the DOM (Btw, in GWT, this process is called to sink and to unsink events, where the former enables a specific event to be triggered and the latter disables it).
I found a workaround by creating my own Anchor class and forcing the underlying GWT Anchor to update the list of events to be sunk.

...
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Event;

public class Anchor extends com.google.gwt.user.client.ui.Anchor {

	@Override public void setEnabled(boolean enabled) {
		super.setEnabled(enabled);
		if (isAttached()) {
			onDetach();
			if (enabled) {
				sinkEvents(Event.ONCLICK);
			} else {
				unsinkEvents(Event.ONCLICK);
			}
			onAttach();
		}
	}

	@Override protected void onLoad() {
		super.onLoad();
		if (isEnabled()) {
			sinkEvents(Event.ONCLICK);
		} else {
			unsinkEvents(Event.ONCLICK);
		}
	}
}

Note the onLoad method, it sets up the state when the widget gets attached to the DOM the first time. It is required because setEnabled() could have been called before the anchor got attached.

If you encountered the same issue, please vote for this bug report.