5

The opposite of this question: How do I add a type to GWT's 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?

Community
  • 1
  • 1
Bluu
  • 5,226
  • 4
  • 29
  • 34
  • What's your design goal? security? performance? – Tahir Akhtar Jan 22 '10 at 20:08
  • 1
    Performance, in a word: to reduce the size of the JS now and in the future. If we start to send Sets and Maps over RPC, there will be another class explosion. The other goal is to maintain best coding practices. If there's a security issue I'm not seeing, let me know. – Bluu Jan 22 '10 at 21:39
  • This seems to me to have a very simple solution. Obviously you know what that is, as you stated it yourself. Why go to so much trouble of trying to change GWT? That seems silly. In the future, should you ever need to return LinkedList, then you can change to an interface. I think if your design goal is performance, then just change the return type to ArrayList and be done with it. My 2 cents. – JP Richardson Jan 25 '10 at 15:35
  • Good point. But why let GWT change me? Guess I'd still like to see the opposite response. – Bluu Jan 30 '10 at 19:36

2 Answers2

8

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
  • 5,226
  • 4
  • 29
  • 34
6

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
  • 16,998
  • 13
  • 66
  • 90
  • However, it is still broken that this "add everything possible during compile time". Because compile time in GWT is not necessary after the server, not even same classpath. The possible runtime exception of unrecognized class during RPC desensitization cannot be eliminated. – Dennis C May 23 '18 at 10:50