GWT, standard library, and IncompatibleRemoteServiceException

The GWT is a set of programs that allows developers to write Java code and compile it down into Javascript to be run on browsers. This requires you to use the subset of Java that the toolkit can emulate, but the compile-time and runtime error messages it displays are often not very useful.

I was developing a GWT application with Eclipse and ran into a client-server communication issue that manifested at runtime. The client would request an object from the server, the object would properly serialize and deserialize (verified by JS debugger), and then GWT's glue code would throw IncompatibleRemoteServiceException (saying "This application is out of date, please click the refresh button on your browser.")

Ultimately, I believe this exception was occurring because either

  1. the class in question extended java.util.EnumMap, a standard Java library class that GWT reimplements in JS, or
  2. accessing Whatever.class is disallowed in GWT, but is required for generic code that deals with enumeration types.

When I rewrote the class to itself reimplement EnumMap (but specialized to a specific Enum), the exception disappeared. Read on for gory Java details:

EnumMap maps values of an Enum to values of some other type. In my case, I was mapping to Boolean values, creating a selection of the Enum. Ordinarily I would just use EnumMap<MyEnum, Boolean>, but unfortunately, EnumMap is not Serializable, since it has no nullary constructors. And why is this? Well, its constructors need to retrieve the list of enumeration values, and not only do Java generics erase the type information that would otherwise allow access to this info, but one also cannot call T.values() where T is a parameter type extending Enum. Basically, it's a whole pile of language-design fail.

I tried to get around all these issues by subclassing EnumMap and calling super(MyEnum.class) in the constructor, allowing it to be nullary (and therefore supporting serialization.) Ultimately, however, this code was rejected by GWT, and I found it easier to just write a specific reimplementation of the library code.

(Eclipse 3.4 x64 on Ubuntu Intrepid Ibex x64, GWT 1.6.4 plugin, ia32 Sun Java 5 libs.)


Comments are closed.