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
- the class in question extended
java.util.EnumMap, a standard Java library class that GWT reimplements in JS, or
Whatever.classis 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 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.)