Serializing an ArrayList of ValueObjects

12 views
Skip to first unread message

jasonpai

unread,
Aug 18, 2006, 10:35:05 AM8/18/06
to Google Web Toolkit
I have a problem after changing to GWT 1.1:
In myService, I return a List of ValueObjects (containing an id, a
HashMap and some Strings). I triple checked this, the List _is_ filled
with the correct objects.
In myAsyncCallback I iterate over the result (which I casted into a
List), checking the GWT.getTypeName information.
1. An object of type ValueObject
2. A String, which _value_ is the _key _ of one of the properties of
the ValueObject. That means, that the Iterator of that ArrayList
returns me the key of a HashMap which is a member of the value I
expected.
3. A String, which is the value to the preceding key.

I triple checked the ArrayList before serialization and I have no clue
what's wrong. Any idea if this is some bug, or how I may verify that it
is one? Recommendations on how to solve this are of course welcome, too
;)

.jasonpai

Miguel Méndez

unread,
Aug 18, 2006, 1:11:04 PM8/18/06
to Google-We...@googlegroups.com
Jason,

Are you using the gwt.typeArgs annotation in your service definition?  (Please see: http://code.google.com/webtoolkit/documentation/com.google.gwt.doc.DeveloperGuide.RemoteProcedureCalls.SerializableTypes.html for more information.)

Also, could you show/send me your service interface definition and the classes that you are sending across?  This information will allow me to dig further.

peter

unread,
Aug 18, 2006, 3:42:49 PM8/18/06
to Google Web Toolkit
Make sure:
1. your ValueObject implements IsSerializable, and
2. the service interface has
/**
* @gwt.typeArgs <com.xxx.client.ValueObject>
*/
public ArrayList methodName();

HTH,
peter

jasonpai

unread,
Aug 21, 2006, 11:04:57 AM8/21/06
to Google Web Toolkit
Hi Miguel,

I am using the gwt.typeArgs annotation in both, the service interface
and the HashMap of the value object. In prior versions of the project
and gwt, I dind't do that, but it always worked fine.

Can't post the real source here, i dunno if my boss would like that.
let me assure you, my interfaces and my valueObject just worked fine in
1.0.21 and basically look like this:

public interface TaskService extends RemoteService {

/**
* @gwt.typeArgs <de.dialogdata.xxxx.WebVO>
*/
public List getTasks(.........) {
//do things, return an ArrayList of WebVO objects.
}
}

while WebVO basically is:

public class WebVO extends WebVOStub implements IsSerializable {

public WebVO() {

}

public WebVO(long id, String type, String peTitle) {
super(id, type, peTitle);
}

/**
* @gwt.typeArgs <java.lang.String, java.lang.Object>
*/
private HashMap properties = new HashMap();

/**
* @gwt.typeArgs <java.lang.String, java.lang.String>
*/
private HashMap propertyTypes = new HashMap();

// some accessor functions
}

while WebVOStub only has id, title and type as members + getter/setter
for these.

In my Service, I convert 3 Task objects to WebVO and dump them to the
log before returning an ArrayList containing these three. It may be of
interest that the first property which gets dumped by an Iterator of
properties.getKeySet().iterator() is called "classname" with the value
"de.dialogdata.xxx.Task"

When this ArrayList is sent over the wire and passed to my
CallbackHandler, I take an Iterator and dump the GWT.getTypeName and
toString of what was returned by that iterator. the first value is an
WebVO object the second is a String with the value "classname" the
third is a String with the value "de.dialogdata.xxx.Task".

That didn't change a bit when putting the gwt.typeArgs annotations to
Interface and WebVO stub (which I did before posting the first time).
Might the serialized response be of any help?

{OK}[0,-22,-16,-20,-14,-19,-12,-19,-10,-21,-8,-20,-6,-19,-4,7,3,54,19,-16,32,8,-14,27,4,-12,26,4,-10,12,50,11,10,-8,76,8,-6,6,4,-4,7,3,2,0,-22,-16,-20,-14,-19,-12,-19,-10,-21,-8,-20,-6,-19,-4,7,3,53,19,-16,1,8,-14,25,4,-12,24,4,-10,12,50,11,10,-8,44,8,-6,6,4,-4,7,3,2,0,23,4,-16,-20,-14,-19,-12,-19,-10,22,4,-8,21,4,-6,20,4,-4,7,3,52,19,18,4,56,8,17,4,16,4,15,4,14,4,13,4,12,50,11,10,9,4,99,8,7,4,6,4,5,4,7,3,2,3,1,["java.util.ArrayList/3821976829","de.dialogdata.xxx.WebVO/2839171777","java.util.HashMap/962170901","java.lang.String/2004016611","classname","de.dialogdata.xxx.Task","importance","java.lang.Integer/3438268394","owner","de.dialogdata.xxx.WebVOStub/3359126777","jasonpai","de.dialogdata.xxx.User","description","Implement
a prototype with EJB3 and GWT.","name","Implement
prototype.","priority","id","java.lang.Long/4227064769","java.lang.String","int","de.dialogdata.xxx.WebVOStub","long","Design
and implement a library.","Entity to ValueObject conversion.","Show
graphical unimpressing demo.","Presentation."],0,2]


greets

jason

Miguel Méndez

unread,
Aug 21, 2006, 2:20:11 PM8/21/06
to Google-We...@googlegroups.com
Interesting...  I do see that you are using gwt.typeArgs which is a good thing.  The WebVO the gwt.typeArgs for the properties member is technically incorrect since java.lang.Object is never serializable although that should not explain the problem that you are seeing. 

If you received something that the client could not deserialize, I would expect that you would see an exception on the client.  From the encoded response it appears that the server is sending a de.dialogdata.xxx.WebVOStub to the client, the "de.dialogdata.xxx.WebVOStub/3359126777" in the response.  This should cause an exception...

Are you not seeing any exceptions on the client?  Are you sure that you are running a 1.1.0 based system on both the client and server?
--
Miguel

peter

unread,
Aug 22, 2006, 11:39:18 AM8/22/06
to Google Web Toolkit
Jason - Maybe I'm missing something here, but why are you implementing
the "getTasks()" method in the interface? First, it is not legal java
code, and second, the method should be implemented in the servlet.
What am I missing here?

jasonpai

unread,
Aug 24, 2006, 7:19:31 AM8/24/06
to Google Web Toolkit
yeah, in the meantime I made real real shure that no old .jar is in the
project. I even deployed to a new jboss installation to make absolutly
shure that there are no old ones somewhere.
I see no exceptions in the client.

I tried to reproduce the propblem in a simple HelloWorld-RPC style,
using the WebVO/WebVOStub classes, but in this clean project, my
ArrayList just gets over the wire without a problem.
As a next step, I took the dummydata out of the demo and used it in my
original app to make sure that the false serialization is not dependend
of the data structure in my app. Then I took both serialized Strings
(onAfterSerialization) and compared them:

Here is what gets Serialized in my app:

10:01:13,827 INFO [STDOUT] {OK}[

0,
-22,
-16,
-19,
-14,
-19,
-10,
-21,
-8,
-20,
-6,
-19,
-4,
6,
3,
44,
8,
-16,
26,
4,
-14,
25,
4,
-10,
-9,
-8,
61,
8,
-6,
-5,
-4,
6,
3,
2,
0,
-22,
-16,
-19,
-14,
-20,
-12,
-19,
-10,
-21,
-8,
-20,
-6,
-19,
-4,
7,
3,
43,
8,
-16,
24,
4,
-14,
1003,
8,
-12,
23,
4,
-10,
-9,
-8,
60,
8,
-6,
-5,
-4,
7,
3,
2,
0,
22,
4,
-16,
-19,
-14,
-20,
-12,
-19,
-10,
21,
4,
-8,
20,
4,
-6,
19,
4,
-4,
7,
3,
42,
8,
18,
4,
17,
4,
16,
4,
1001,
8,
15,
4,
14,
4,
13,
4,
12,
23,
11,
10,
9,
4,
59,
8,
7,
4,
6,
4,
5,
4,
7,
3,
2,
3,
1,


[

"java.util.ArrayList/3821976829",
"de.dialogdata.lib.evo.api.WebVO/2839171777",


"java.util.HashMap/962170901",
"java.lang.String/2004016611",
"classname",

"de.dialogdata.dummy.TypeName",


"importance",
"java.lang.Integer/3438268394",
"owner",

"de.dialogdata.lib.evo.api.WebVOStub/3359126777",
"jasonpai",
"de.dialogdata.dummy.DummyUserType",
"description",
"The description of the first dummy object.",
"priority",
"name",
"The first dummy object.",
"id",
"java.lang.String",
"int",
"de.dialogdata.demo.gwt.client.ValueStub",
"long",
"The description of the second dummy object.",
"The second dummy object.",
"The description of the third dummy object.",
"The third dummy object."

],0,2]

And this is the same (except the value object reside in another
package) ArrayList serialized by my simple rpc demo app:

09:56:03,465 INFO [STDOUT] {OK}[

6,
44,
26,
0,
-22,
-16,
-19,
-14,
-19,
-10,
-21,
-8,
-20,
-6,
-19,
-4,
6,
3,
44,
8,
-16,
26,
4,
-14,
25,
4,
-10,
-9,
-8,
61,
8,
-6,
-5,
-4,
6,
3,
2,
6,
43,
24,
0,
-22,
-16,
-19,
-14,
-20,
-12,
-19,
-10,
-21,
-8,
-20,
-6,
-19,
-4,
7,
3,
43,
8,
-16,
24,
4,
-14,
1003,
8,
-12,
23,
4,
-10,
-9,
-8,
60,
8,
-6,
-5,
-4,
7,
3,
2,
6,
42,
17,
0,
22,
4,
-16,
-19,
-14,
-20,
-12,
-19,
-10,
21,
4,
-8,
20,
4,
-6,
19,
4,
-4,
7,
3,
42,
8,
18,
4,
17,
4,
16,
4,
1001,
8,
15,
4,
14,
4,
13,
4,
12,
23,
11,
10,
9,
4,
59,
8,
7,
4,
6,
4,
5,
4,
7,
3,
2,
3,
1,

[

"java.util.ArrayList/3821976829",
"de.dialogdata.demo.gwt.client.WebVO/1531517602",


"java.util.HashMap/962170901",
"java.lang.String/2004016611",
"classname",

"de.dialogdata.dummy.TypeName",


"importance",
"java.lang.Integer/3438268394",
"owner",

"de.dialogdata.demo.gwt.client.WebVOStub/1094047757",
"jasonpai",
"de.dialogdata.dummy.DummyUserType",
"description",
"The description of the first dummy object.",
"priority",
"name",
"The first dummy object.",
"id",
"java.lang.String",
"int",
"de.dialogdata.demo.gwt.client.ValueStub",
"long",
"The description of the second dummy object.",
"The second dummy object.",
"The description of the third dummy object.",
"The third dummy object."

],0,2]

if you compare these, you'll notice that they are nearly identical,
except that the app-string misses three numbers at the very beginning
and at two other places. one of these numbers is always the id of one
of the serialized objects.

I dunno why this happens, it could have s.th. to do with the baseclass
WebVOStub which happens to have three members (but is pure speculation
at this point).

Any ideas how to proceed?

.jason

Miguel Méndez

unread,
Aug 25, 2006, 1:06:49 PM8/25/06
to Google-We...@googlegroups.com
Jason,

What does the WebVOStub look like?  I don't recall seeing a definition for it.  Also, did you use the real WebVOStub class in your isolated test or the real one?

"de.dialogdata.lib.evo.api.WebVOStub /3359126777",



--
Miguel

jasonpai

unread,
Aug 27, 2006, 6:09:22 AM8/27/06
to Google Web Toolkit
I used the real WebVOStub and WebVO classes in my isolated example
(although they did change their package).

public class WebVO extends WebVOStub implements IsSerializable {

private boolean readOnly = true;

public WebVO() {

}

public WebVO(long id, String type, String peTitle, boolean readOnly) {
super(id, type, peTitle);
this.readOnly = readOnly;
}

/**
* @gwt.typeArgs <java.lang.String, java.lang.Object>
*/
private HashMap properties = new HashMap();

/**
* @gwt.typeArgs <java.lang.String, java.lang.String>
*/
private HashMap propertyTypes = new HashMap();

public Object get(String propName) {
return properties.get(propName);
}

public void set(String propName, Object value) {
properties.put(propName, value);
}

public String getType(String propName) {
return (String)propertyTypes.get(propName);
}

public void setType(String name, String type) {
propertyTypes.put(name, type);
}

public Set getPropNames() {
return properties.keySet();
}

public boolean isReadOnly() {
return readOnly;
}
}

greets,
jason

Miguel Méndez

unread,
Aug 28, 2006, 10:25:45 AM8/28/06
to Google-We...@googlegroups.com
Jason,

At this point I do not think that I have enough information to help you further.  The declaration of WebVO looks okay.  If I understood you correctly, your isolated test case works fine against your dummy data but the real application fails to work when using this same dummy data.  Something piece of the puzzle is missing.

You may want to try one or all of the following items:
  1. If WebVOStub is not serializable then it cannot be sent to the client.  Figure out where in the server this is happening and fix it.
  2. Try version 1.1.10 - It includes fixes to the serialization system
  3. Debug the client-side proxy code in hosted mode.  (You will need to give the -gen option to the GWTShell class.  This option specifies the the directory into which the GWTCompiler and the GWTShell will place the generated code.  The usage is -gen <path to generated output directory>.  The name of the autogenerated proxy class will be the name of your service interface with _Proxy appended to it.)
HTH,
--
Miguel

Miguel Méndez

unread,
Oct 2, 2006, 9:44:25 AM10/2/06
to Google-We...@googlegroups.com
Hello Jason,

I think that what you are seeing maybe related to a classloader issue that Ian reported on the group: http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/ade31fb9b0a26f02.  I will need to setup a JBoss install in order to debug this problem further.  I'll try to squeeze this in over the next week and respond back on this thread.

If you have additional information please send it my way.  (A simple JBoss enabled project that demonstrates the problem would be greatly appreciated.)

Thanks,
--
Miguel
Reply all
Reply to author
Forward
0 new messages