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.

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.

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.

Java Cookies from the Future Past

While working with cookies in Java/GWT and thus—to set the expire date—with Date, I found a doubtful Java behavior.

My goal was to set a cookie to expire in about one month from today like this:

Date expires = new Date(new Date().getTime() + 1000 * 60 * 60 * 24 * 30);
Cookies.setCookie("myCookie", "myData", expires);

And kept wondering why the cookie never got stored.

And finally created a simple test case like this:

Date today = new Date();
Date tomorrow = new Date(today.getTime() + 1000 * 60 * 60 * 24);
Date nextMonth = new Date(today.getTime() + 1000 * 60 * 60 * 24 * 30);

And got following dates:

today=Mon Feb 07 14:27:50 CET 2011
tomorrow=Tue Feb 08 14:27:50 CET 2011
nextMonth=Tue Jan 18 21:25:02 CET 2011

According to Java’s calculation, the cookie was expired already before even being set.

Took me a bit to understand why:
1000 * 60 * 60 * 24 * 30 = 2,592,000,000 = 0x9A7EC800
Thus, the first bit got set to one… a classical overflow causing the integer value to become negative – just try:

System.out.println(1000 * 60 * 60 * 24 * 30);

It will print out -1702967296.

Fix: Add a little L will solve the issue by forcing the compiler to calculate using the scope of long:

Date nextMonthLong = new Date(today.getTime() + 1000L * 60 * 60 * 24 * 30);

I guess I will fall for that one again sometime as the error is not obvious in my opinion — especially because getTime() returns a long and still, the compiler sticks with an int for the multiplication part.

Authentication with FlickrJ

When you know about username and password logins, the whole Flickr authentication process for web applications seems a little weird on first sight, nevertheless it is logical and necessary after you have done some reading (for example the official Flickr WebApp Auth HowTo).
To get started and into coding quickly (using FlickrJ and Java) I recommend this page. Especially the code example is excellent in my opinion! Thanks Andy Sacher!

Casting collections in Java

Assuming two classes A and B as

class A {}
class B extends A {}

It is just logical that casting B to A works fine:

A anObjectOfClassA = new B();

But when it comes to collections of As and Bs, a strange phenomenon appears in Java:

Collection<B> collectionOfBs = new LinkedList<B>();
Collection<A> collectionOfAs = (Collection<A>)collectionOfBs; // this line does not compile!

That is, though the collection wrapper (the java.util.Collection class) is the same and B extends A, casting a collection of objects of class B to a collection of objects of class A throws an compile-time error.

But it works using generics (the whole class for the sake of completeness and reusability):

import java.util.Collection;
import java.util.LinkedList;

public class CollectionCastingExample {

  class A {}
  class B extends A {}
	
  Collection<B> collectionOfBs = new LinkedList<B>();
//  Collection<A> collectionOfAs = (Collection<A>)collectionOfBs;
	
  Collection<A> collectionOfAs = downCastCollection(collectionOfBs, A.class);
	
  /**
   * Casts a collection of objects of class B where B extends A to a collection of objects of class A.
   * 
   * @param <T> Base class
   * @param collection Collection of objects of a class extending T 
   * @param aClass Representation of T
   * @return Collection of objects of T casted from given collection of objects of a class extending T.
   */
  @SuppressWarnings("unchecked")
  public static <T> Collection<T> downCastCollection(Collection<? extends T> collection,
      Class<T> aClass) {
    return (Collection<T>) collection;
  }
}

Despite the fact that a @SuppressWarnings("unchecked") is required, it avoids iterating over the whole collection of Bs and casting each of them from B to A plus adding them to a new collection of As.

Uploading File to Server: Access Denied

Simple task: upload a file to the server. Achieved so far: upload form works and the file gets transferred to the server.
But as soon as the file is written, I get one of that:
“java.security.AccessControlException: access denied (java.io.FilePermission /some/folder/upload__71c20601_12b1b66bc39__7ffa_00000000.tmp write)”
I am amazed how much searching is required to find some information about how to modify the file permissions for the local app engine! And in the end, it turns out that there is an issue with the GAE on Mac but without a way to configure the local Jetty server to allow write access. 🙁
As soon as I deploy the app to a Tomcat on Linux, it works like a charm!