gwt - Using List<Serializable> in a RPC call?

Garagos picture Garagos · Jun 17, 2010 · Viewed 9.8k times · Source

I have a RPC service with the following method:

public List<Serializable> myMethod(TransactionCall call) {...}

But I get a warning when this method is analyzed, and then the rpc call fails

Analyzing 'my.project.package.myService' for serializable types
Analyzing methods:
public abstract java.util.List<java.io.Serializable> myMethod(my.project.package.TransactionCall call)
Return type: java.util.List<java.io.Serializable>
[...]
java.io.Serializable
Verifying instantiability
(!) Checking all subtypes of Object which qualify for serialization

It seems I can't use Serializable for my List... I could use my own interface instead (something like AsyncDataInterface, which implements the Serializable interface) but the fact is that my method will return a list custom objects AND basic objects (such as Strings, int....).

So my questions are:

  • Is it a standard behavior? (I can't figure out why I can't use this interface in that case)
  • Does anyone have a workaround for that kind of situation?

Answer

Ashwin Prabhu picture Ashwin Prabhu · Jun 17, 2010

When passing objects across RPC call's its a good practice to declare concrete parameter types in the RPC interface. If for some reason you cannot use concrete class in the RPC interface try to be as specific as possible.

This is because the GWT compiler while emitting javascript has to take into account all possible variants of List in the compilation unit. This includes all the classes extending List and Serializable interface in the class path. The permutations can be huge, which will effect your compile time as well as the application download size.

So the best approach is to define your interface as

public ArrayList<YourType> myMethod(TransactionCall call) {...}

rather than

public List<Serializable> myMethod(TransactionCall call) {...}

That way compiler has to generate compilation units for ArrayList and YourType extensions only. The benifit is in faster compile times and smaller compiled javascript files, hence faster downloads of your application.

In case you have to return a wide range of unrelated objects in your RPC call, try creating a wrapper class and return object of the wrapper class with the return value wrapped. Use the wrapper class in the RPC method definition. Resist the urge to declare the wrapped field as Object or Serializable, you will negate all serialization benefits you gained by using a wrapper. Instead you can define a Wrapper interface and a small set of Wrapper implementation for each concrete type you wish to return through your RPC call.