GWT is a very useful programming framework but sometime it’s very difficult to find out how to solve some problems.
One of the is related to GWT-RPC Serialization. GWT-RPC is the canonical way to make AJAX call from GWT Client to GWT Server passing Serializable beans (more details on GWT web site – http://code.google.com/webtoolkit/doc/latest/tutorial/RPC.html).
To pass a bean you have to fulfill the following requirements (from GWT site):
- It implements either Java Serializable or GWT IsSerializable interface, either directly, or because it derives from a superclass that does.
- Its non-final, non-transient instance fields are themselves serializable
- It has a default (zero argument) constructor with any access modifier (e.g. private Foo(){} will work)
Even if you fulfill these requirements may happen that GWT compiler say:
<class name> was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.: instance = <class instance>@<id>
The problem may have different causes. Here his a complete check list to use for solving the problem:
- Verify that the class has a default constructor (without arguments)
- Verify that the class implements Serializable or IsSerializable or implements an Interface that extends Serializable or extends a class that implement Serializable
- Verify that the class is in a client.* package or …
- Verify, if the class is not in client.* package, that is compiled in your GWT xml module definition. By default <source path=”client” /> is present. If your class is in another package you have to add it to source. For example if your class is under domain.* you should add it to xml as <source path=”domain” /> . Be aware that the class cannot belong to server package! More details on GWT page: http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideModuleXml
- If you are including the class from another GWT project you have to add the inherits to your xml module definition. For example if your class Foo is in the package com.dummy.domain you have to add <inherits name=”com.dummy.domain.Foo”/> to the module definition. More details here: http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideInheritingModules
- If you are including the class from another GWT project released as a jar verify that the jar contains also the source code because GWT recompile also the Java source for the classes passed to the Client.
I hope that this help. Please let me know if I miss some check or I wrote something no more valid. This check list is updated for GWT 2.2.
other point – If a class extends abstract class it doesn’t work!
This will kind of seem like an obvious point but… sometimes you get stuck forgetting the most obvious things!
Don’t forget the need to compile with GWT.
I just spent half a day making all kinds of changes to my code that didn’t require it and when I changed a couple of things in the “Shared” package (parallel the Client package) it took me literally hours to figure out that what I was missing was a simple compile. 😛
I just found out, that GWT is not able to serialize Annotation instances (will throw the error discussed here), although they are per definition Serializeable.
Thomas I miss the point. Which kind of behaviour do you expect serializing annotation instances? Here is an example of a domain class with JPA annotations serialized in GWT – https://code.google.com/p/gwt-spring-jpa-lucene/source/browse/com.intre.open.gwtjpa/trunk/src/com/intre/open/gwtjpa/data/first/domain/Person.java.
The GWT compiler interprets the annotation and creates the JavaScript class according.
@giulioroggero – I’m not talking about classes that are annotated, but about Annotation instances that you get when you call class.getAnnotations() Quite the corner case really, The project in which I ran into this issue is generating a CRUD-GUI for arbritarily defined DomainClasses and for that I collect metadata on the server with the reflection API and send it to the client. I’ve got annotations on my DomainClasses that regulate the GUI generation, and normally I just send the values from inside the Annotation, but right before I posted I just used the Annotation instance itself, and this didn’t work out with GWT, so I went back to getting the values out of the Annotation and put it into some variable in my metadata, and this worked as expected.
@kaefert in that case your solution is fine. Another solution is to use Deferred Binding with generate-with directive: http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsDeferred.html#generator.
In that case you can read the Annotation properties and put them inside the JavaScript object without touching your source code.
I have a problem with including the serializable class from another GWT project. This class is in “shared” package and when I try to add <inherits name=”com.another.project.shared.MyClass”/ to the module definition of project ,where I want to include this class, the application doesn't even start .It collapses on loading and stack trace is: Unable to find 'com/another/project/shared/MyClass.gwt.xml' on your classpath; could be a typo, or maybe you forgot to include a classpath entry for source?
Check if the module name is in lower case. This happen linux and mac