It seems that the issue of having a mechanism for generic GWT-RPC object serialization comes up frequently. While the motivation by the developer for being able to do this in their code varies, the end result is generally the same: a reference explicitly or implicitly is made for GWT to serialize java.io.Serializable which then triggers the GWT compiler to "go crazy" and generate code for every serializable object on the class path. In the best case, this merely results in bloated code; in the worst case, it results in a project that fails on the server with ClassNotFound exceptions during GWT-RPC (I can provide the specifics if anyone is interested).
In the situations that I have encountered, the developer typically wants to build a generic GWT-RPC service where all they know about the type of the argument(s) or return value is that GWT can serialize it...the type may be a type from the JRE that GWT emulates (String, Long, Date, etc) and can serialize or an object of their own creation which I will assume can be made to implement com.google.gwt.user.client.rpc.IsSerializable. The other common case is the desire to pass or return collections such as List<Object> or Map<String, Object> where, again, the developer only knows that Object will be of a type that GWT can serialize. There is a thread from 2008 (http://groups.google.com/group/Google-Web- Toolkit-Contributors/browse_thread/thread/25d151960b48b5c4#) that proposes one possible workaround. Before finding that solution, I invented one on my own and posted it in response to a forum post on the StackOverflow list (http://stackoverflow.com/questions/2210226/how- can-i-keep-gwt-from-trying-to-include-every-serializable-class-when-i- use-arr/3385509#3385509); unfortunately, my post hasn't received any feedback. I don't feel nearly as strongly about the specific implementation of a solution as I do that developers shouldn't have to invent workarounds like this on their own. To that end, I am posting my implementation (see below) for a class called RpcObject, and I would like feedback: is the implementation sound, or are there suggestions for improvement? should a class of this sort be provided by GWT? is there interest in having it be a project of GWT-contrib? In the event that I am native in my understanding of GWT-RPC and there is already a better way to accomplish this [or there is one on the roadmap], please let me know. -Jeff import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import com.google.gwt.user.client.rpc.IsSerializable; public class RpcObject implements IsSerializable { protected HashMap<String, IsSerializable> rpcObjectWrapper = new HashMap<String, IsSerializable>(); /* * NOTE: The following fields are here to * trick/fool/work-around/whatever-you-want-to-call-it GWT-RPC's * serialization policy. Having these types present, even though their * corresponding fields are never used directly, enables GWT-RPC to * serialize/deserialize these primitive types if they are encountered in * the rpcWrapperObject! Of course GWT-RPC already knows how to serialize * all these primitive types, but since, for example, String doesn't * implement GWT's IsSerializable interface, GWT has no expectation that it * should ever be allowed in the rpcWrapperObject instance (and thus String, * as well as all the other Java primitives plus Arrays of such types as * well as List, Set, and Map, won't be part of the serialization policy of * the RpcObject type). This is unfortunate because thanks to java type * erasure, we can easily stuff Strings, Integers, etc into the wrapper * without any issues; however, GWT-RPC will cowardly refuse to serialize * them. Thankfully, it appears that the serialization policy is for the * RpcObject type as a whole rather than for the rpcObjectWrapper field * specifically. So, if we just add some dummy fields with these "primitive" * types they will get added to the serialization policy (they are * effectively white-listed) of the type as a whole, and alas, GWT- RPC stops * cowardly refusing to serialize them. */ protected Byte _byte; protected Short _short; protected Integer _integer; protected Long _long; protected Float _float; protected Double _double; protected Date _date; protected Boolean _boolean; protected Byte[] _bytes; protected Short[] _shorts; protected Integer[] _integers; protected Long[] _longs; protected Float[] _floats; protected Double[] _doubles; protected Date[] _dates; protected Boolean[] _booleans; protected List<String> _list; protected Set<String> _set; protected Map<String, String> _map; public RpcObject() { super(); } public RpcObject(final Object value) { super(); this.setValue(value); } @SuppressWarnings("unchecked") public <X> X getValue() { HashMap h = (HashMap) rpcObjectWrapper; X value = (X) h.get("value"); return value; } @SuppressWarnings("unchecked") public void setValue(Object value) { HashMap h = (HashMap) rpcObjectWrapper; h.put("value", value); } } -- http://groups.google.com/group/Google-Web-Toolkit-Contributors