views:

107

answers:

2

The opposite of this question: http://stackoverflow.com/questions/138099/how-do-i-add-a-type-to-gwts-serialization-policy-whitelist

GWT is adding undesired types to the serialization policy and bloating my JS. How do I trim my GWT whitelist by hand? Or should I at all?

For example, if I put the interface List on a GWT RPC service class, GWT has to generate Javascript that handles ArrayList, LinkedList, Stack, Vector, ... even though my team knows we're only ever going to return an ArrayList. I could just make the method's return type ArrayList, but I like relying on an interface rather than a specific implementation. After all, maybe one day we will switch it up and return e.g. a LinkedList. In that case, I'd like to force the GWT serialization policy to compile for only ArrayList and LinkedList. No Stacks or Vectors.

These implicit restrictions have one huge downside I can think of: a new member of the team starts returning Vectors, which will be a runtime error. So besides the question in the title, what is your experience designing around this?

+2  A: 

While no good framework should ever try to change its users, let me try to explain why GWT serialization works the way it does. I don't know the exact mechanics of this, so I could be wrong, but this is the gist of what I've seen.

GWT already removes extra code outside of the RPC interfaces - for instance, if you take an app without RPC, you're free to use interfaces like List and Map and Set to your hearts content - GWT will automatically only include the implementations which you actually use. Why? Because it has access to your code, and is capable of actually going through all visible permutations of the code and pruning unused classes. So GWT actually does not create class explosions when interfaces are used.

The problem is entirely the RPC. The point of an RPC service is that the server needs to implement an RPC interface - which means that if the interface dictates that a method needs to return a list, the server is free to return any implementation of the list it wants to, as long as it can be serialized.

Thats the problem - GWT has absolutely no way to know what implementation of an interface a server will use, either at compile time or at some point in the future. The server code can, and in many cases will, be developed independently of the client side code. So the only way to safely receive an object of type List over the wire is to know about every possible implementation of it beforehand.

Sudhir Jonathan
A: 

There is a property that can do this class blacklisting. For example, to blacklist non-ArrayList Collections, add these lines to your *.gwt.xml:

<extend-configuration-property name="rpc.blacklist" value="java.util.HashSet"/>
<extend-configuration-property name="rpc.blacklist" value="java.util.LinkedHashSet"/>
<extend-configuration-property name="rpc.blacklist" value="java.util.LinkedList"/>
<extend-configuration-property name="rpc.blacklist" value="java.util.Stack"/>
<extend-configuration-property name="rpc.blacklist" value="java.util.TreeMap"/>
<extend-configuration-property name="rpc.blacklist" value="java.util.TreeSet"/>
<extend-configuration-property name="rpc.blacklist" value="java.util.Vector"/>

This was necessary for me to reduce JS size when sending GWT's built-in com.google.gwt.user.client.ui.SuggestOracle$Response objects over the wire. Such objects contain a java.util.Collection, but I knew I would only ever be sending back an ArrayList.

I still respect the advantages of compile-time checks as discussed in the other responses, comments, and my original question. Indeed, this is a flaky solution if GWT starts picking up additional implementations to serialize (why is this not a whitelist?). However this "rpc.blacklist" property saved me from rolling my own SuggestOracle just to get a more specific collection type.

Bluu