Thursday, September 18, 2014

Re: GWT 2.2.0 does not serialize/deserialize basic Java types if not referenced explicitly

One thing that I do to prevent rpc serlizer generation explosion as well is to use the following in my base gwt.xml module:

<extend-configuration-property name="rpc.blacklist" value="-.*\.client\..*"/>
<extend-configuration-property name="rpc.blacklist" value="-.*\.shared\..*Service"/>
<extend-configuration-property name="rpc.blacklist" value="+.*\.client\..*Exception"/>
<extend-configuration-property name="rpc.blacklist" value="+.*\.client\.rpc\..*"/>

This basically prevents anything in the client package that is not an exception or used in the RPC process from being added to the GWT generated serialization policy.  In the shared package, it prevents "Service" interfaces from being added to the serialization policy as well, as long as the class name ends in service.

On Tuesday, September 16, 2014 6:51:56 PM UTC-7, Justin Zhang wrote:
I'm so excited to see so many quality replies. This is really the place to get in-depth knowlege of GWT.

Regarding my own issue, the service interface was designed a couple of years by someone who is no longer with the company. I just want to explore the possibility to upgrade GWT to have better tooling with minimal changes to the legacy code.

  I understand the current service interface design does not work the pricinple of GWT-RPC serialzation/deserialization. But it avoids a great number of similar looking service methods or the need of value object. I'm just wondering if we can enhance the RPC policy file generation code to consider additional hints for generic types like Object. The hints indicate what specific types like java.lang.Integer, java.util.Date will the generic type be at runtime. The specification of specific types can be an annotation in the service interface or deferred binding config in module xml.

  Thank you very much!
On Monday, September 15, 2014 1:37:35 AM UTC-7, Thomas Broyer wrote:


On Monday, September 15, 2014 6:57:24 AM UTC+2, Justin Zhang wrote:
Hi GWT experts,
  I had a problem with the GWT-RPC on 2.2.0 and above.

  I have a generic service interface which serves as multiple RPC
requests depending on the value of event parameter:

    @RemoteServiceRelativePath("Service")
    public interface Service extends RemoteService {
        EventResult execute(String event, Map<String, Object> eventData)
                throws ServiceException;
    }

The details of request are passed as Map with String key and the value (the eventData)
can be String, Integer, Double and Date (java.util.Date precisely).
This works well on GWT 1.6.4. But when I try to upgrade to 2.2.0 (for
better dev mode tool),


You couldn't have chosen a worse moment to finally move from Hosted Mode to Dev Mode!
Just when Dev Mode is only still supported by Internet Explorer and everyone's switching to Super Dev Mode (which the GWT Team is working on all rage to get you a better dev experience in the upcoming GWT 2.7)

 
it complains that:

    Type 'java.util.Date' was not included in the set of types which can
be deserialized by this SerializationPolicy or its Class object could
not be loadded. For security purposes, this will not be deserialized.

I came across an SO post on a workaround to add the problematic type
explicitly to a dummy method. For instance to get past the java.util.Date
issue, you modify the above interface like:

    @RemoteServiceRelativePath("Service")
    public interface Service extends RemoteService {
        EventResult execute(String event, Map<String, Object> eventData)
                throws ServiceException;

This was a really bad idea. You should use the most specific types as possible in your RPC interfaces and transfer-objects (it's not news, it has always been that way, it's just become stricter over time).
So HashMap (or LinkedHashMap or TreeMap) rather than Map, and NOT Object.
In that specific case, create a value object that can transport any of your supported value types; either use one object with as many properties as the types you support (stringValue, intValue, doubleValue, dateValue) and use the one field that's not null, or create a base class and as many subclasses each wrapping a single value (e.g. new StringValue("foo"), new IntValue(42), etc.) and use instanceof on that wrapper class.
That way, by static analysis of your code and class hierarchy, GWT can know exactly which types you'll send over the wire, and it will generate the code to handle all of those types, and only those types (not too few –causing errors like you're seeing–, not too many –generating bloated code–).
…or better yet, create specific event objects (whether they all inherit from a base class so that you can use a single, polymorphic execute() service method is up to you; I, for one, would rather use specific methods, possibly using multiple arguments rather than event objects then).
 
        void dummy(Date date);
    }

Since the GWT 1.6.4 serialize/deserialize the basic Java types
correctly, I'm wondering if there is a better way to avoid messing up
the service interface. For instance, add some special configuration in
the module xml file to instruct the RPC policy generator always allow
serialization/deserialization of basic Java types.

There's a blacklist of types, but no whitelist, no.

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit+unsubscribe@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at http://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment