Cry of desperation: When will serialisation be fixed?

6 views
Skip to first unread message

georgeuoa

unread,
Jul 4, 2006, 10:29:36 AM7/4/06
to Google Web Toolkit
Sorry for the catchy title, but I've already posted this three times in
the last weeks [1], I got no reply (so I still don't know where I
should stand!) and the concrete bug is unfortunately a K.O. for me as
the only workaround I can think of is my own RPC implementation.

The concrete issue is what I believe to be a severe bug in RPC
serialisation: java.util.List implementations do not serialise
correctly form the client to the server (the other direction works
fine) and often refer objects that were never added to them. I have
many (some are trivial) examples where objects containing many members
and lists which point also to that members do not survive the trip over
the wire.

I am writing an application which allows the user to manipulate a query
graph on the client side - this is fairly complex, but again, I like
GWT because it's the only that can do that!

However, I can't send these graphs back to the server now, since they
always end up broken, the collections contained in there point to
members of other objects. If there was a runtime-checking on the server
side, this would result in a ClassCastException!

Of course I can't rule out the possibility that I'm completly wrong on
this matter but, if so, please do tell us. On the other hand, if the
GWT team is already aware of this, please also do tell us so (I found
nothing on the orphaned issue tracking list) that we don't get into the
tedious task of reinventing the wheel.

Thank you for your attention :-)
G.

[1]
http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/c57fcbc11345165c/612a07e60b22f962?q=georgeuoa&rnum=9#612a07e60b22f962
http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/b069f515ae967fd4/153a6d019d998fd2?q=georgeuoa&rnum=22#153a6d019d998fd2
http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/1b29be75d1b47ed/879c8438d50072bc?q=georgeuoa&rnum=26#879c8438d50072bc

ash

unread,
Jul 4, 2006, 9:13:22 PM7/4/06
to Google Web Toolkit
i think a lot of us here have shared your pain. ive resorted to
injecting byte-code into the google compiler aop style to solve
problems.

however wrt your problem. i frankly have not experienced it in (semi)
_hosted_ mode.
note, semi-hosted mode to me means debugging client as java, and
debugging server in sysdeo tomcat eclipse plugin.

note, this does not mean that problem does not manifest itself when
running the resultant pure javascript solution.

im using build 1.0.21 as a base, remember, i however use my own user
jar.

here is what i tested for you:

// service ctx:
public interface WikiService extends RemoteService {
public ExplorerInfo test(ExplorerInfo arg); // [georgeuoa]

...

public class ExplorerInfo implements IsSerializable {
public String namespace;
public Integer timedRevision;
public long timedDate;
public int permission;
public String parentPath;
public String folderPath;
public String[] subFolders;
public ResourceAttrInfo[] resources;
public List testList = new ArrayList(); // [georgeuoa - i didnt
annotate with gwt.typeArgs]
public Map testMap = new HashMap(); // [georgeuoa - which probably
breaks in pure js mode]
}

...
public class ResourceAttrInfo implements IsSerializable {
public ResourceAttrInfo test; // [georgeuoa]
public String name;
public String parentPath;
public Integer revision;
public long lastModified;
public String lastUpdater;
public Integer lastChangedRevision;
public long size;
public String uuid;
/**
* @gwt.typeArgs <java.lang.String,java.lang.String>
*/
public Map properties = new HashMap();
public String getAbsolutePath() {
String ppWithSlash = parentPath;
if (!ppWithSlash.endsWith("/"))
ppWithSlash += "/";
return ppWithSlash + name;
}
}
...


// client ctx:
...
WikiService.ExplorerInfo ctrlrModel; // class inst var initialised
elsewhere
...
class TestButtonClick implements ClickListener {
public void onClick(Widget sender) {
WikiServiceAsync rpc = (WikiServiceAsync)
Gem.stone.openService(Jump.JUMP_WIKI_SERVICE);
ctrlrModel.testList.add("hello");
ctrlrModel.testList.add("world");
ctrlrModel.testList.add(ctrlrModel.resources[0]);
ctrlrModel.testMap.put("hello", "world");
ctrlrModel.testMap.put("obj-ref", ctrlrModel.resources[1]);
ctrlrModel.resources[1].test = ctrlrModel.resources[0];
rpc.test(ctrlrModel, new TestCallback());
}
}


// server ctx:
public ExplorerInfo test(ExplorerInfo arg) {
arg.testList.add("test for georgeuoa");
arg.testList.remove("hello");
arg.testMap.put("test", "test for georgeuoa");
arg.testMap.put("obj-ref2", arg.resources[0]);
arg.testMap.remove("hello");
arg.resources[0].test = arg.resources[1];
return arg;
}

// ---------------------------
based on this successfully run test in my application with my domain
objects, i can assert the following:
1. rpc marshelling and serialisation works fine on both client and
server [in (semi)hosted mode]
2. object graphs that includes associations to other objects within the
graph are preserved across the wire


therefore, i can only assume that your problem is either:
1. that you didnt annotate your List and specify your element types
which may cause it to trip over in the js generation or
2. the js generated serialisation implementation is defective


i hope this helps,

developing a new svn-reverse-wiki application, a new gwt framework that
i will soon release, maintaining my own user lib distro and debugging
the compiler has had me experience similar desperation! its amazing
what the difference is b/n playing around and developing a large
production application on a beta kernel under a deadline. but then
again, i did sign up for it. i have no idea how others are coping but i
can tell you i feel bloody lucky that i have 10 years of java and 4
years of delphi which has helped me leverage and extend this paradigm.
for those that arent able to make gwt hacks themselves, then i
recommend u wait another 2 months before committing to a production
deliverable using gwt to management.


to google's credit, the user lib may be buggy, but the compiler is
pretty stable although a bit limited. imho google should invest in the
following:
1. growing the emulation subsystem
2. richer compiler support


good luck with your solution.

rgds ash

bruciadmin

unread,
Jul 5, 2006, 1:21:32 AM7/5/06
to Google Web Toolkit
Hi Ash,

I agree with you completely. I can see huge promise in using GWT as an
approach to application development, but I've seen very little response
on the mailing list by the developers which is causing me a bit of
stress.

Of particular note is the lack of usage of interfaces - I understand
Scott's point a while back that he doesn't see the point of
instantiating widgets outside hosted mode, but by not using interfaces,
how can we provide mocks to the objects which depend on Widgets outside
hosted mode. Though it is possible to do, a good framework should
encourage good testability.

I was hoping that any issues found would not require resorting to
solutions like bytecode AOP, but I'm starting to wonder....

On another note, I've been working on a build task which converts a
Spring context of widgets into a pseudo bean factory which can be
compiled by GWT and run on the client side. This should provide a nice
Inversion of Control container to the client for objects (though
probably couldn't do AOP for clientside javascript). Not sure if you'd
be interested (your experience dwarfs mine), but will still keep this
list posted of developments.

georgeuoa

unread,
Jul 5, 2006, 2:29:24 AM7/5/06
to Google Web Toolkit
Ash

Thank you very much for your meticulous analysis!

The serialisation problem I am facing is unfortunately not as trivial
as I initialy thought it was, since I never succeeded in writing a
synthetic test that reproduces it. I will try though to do so, even if
it means that in the end I'll post a 20M war - to whomever it may
concern :-)

I'll be working on this today, so I hope to boil it down to a simpler
example.
br,
g.

georgeuoa

unread,
Jul 5, 2006, 5:25:43 AM7/5/06
to Google Web Toolkit
Dear All!

I did it!

I managed to create a synthetic test that reproduces exactly and
accurately the broken serialisation.
A warning beforehand: it is complicated and subtle, any even slight
deviation and the problem is not reproducible. For code please see [1]
- [10].
The problem has to do as suspected when three factors coincide:
Inheritance, Lists and references to items in the list and happens
exclusively in the direction client -> server.
When the graph is recieved on the server side, the [8]
TFormQuery->model->models(0) is a reference to [3] TDisjuctiveModel
(basically a loop to itself!) instead of the expected
[4] TNumberModel instance. However, if you make two subtle changes in
[10] the submission is error-free:

//CASE 1 ... which demonstrates that multiple references are broken,
please see my report [11]
setActiveModel(null);


AND/OR

//CASE 2 ... which demonstrates that inheritance is broken, please see
my report [12]
column.setRenderer(new TCellRenderer());

Sorry for cluttering
G.

[1] TBaseModel.java
import com.google.gwt.user.client.rpc.IsSerializable;

public abstract class TBaseModel implements IsSerializable{

private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

import java.util.ArrayList;
import java.util.List;

[2] TCompositeModel.java

import java.util.ArrayList;
import java.util.List;

public class TCompositeModel extends TBaseModel {

private List models = new ArrayList();

public List getModels() {
return models;
}

public void setModels(List models) {
this.models = models;
}
}

[3] TDisjuctiveModel.java

public class TDisjuctiveModel extends TCompositeModel {

private TBaseModel activeModel;

public TBaseModel getActiveModel() {
return activeModel;
}

public void setActiveModel(TBaseModel activeModel) {
this.activeModel = activeModel;
}
}

[4] TNumberModel.java

public class TNumberModel extends TCompositeModel {

}

[5] TCellRenderer.java

import com.google.gwt.user.client.rpc.IsSerializable;

public class TCellRenderer implements IsSerializable{

}

[6] TExtendedCellRenderer.java

public class TExtendedCellRenderer extends TCellRenderer{

}

[7] TColumn.java

import com.google.gwt.user.client.rpc.IsSerializable;

public class TColumn implements IsSerializable {

private String name;

private TCellRenderer renderer;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public TCellRenderer getRenderer() {
return renderer;
}

public void setRenderer(TCellRenderer renderer) {
this.renderer = renderer;
}
}

[8] TFormQuery.java

import com.google.gwt.user.client.rpc.IsSerializable;

public class TFormQuery implements IsSerializable{

private TBaseModel model;

private String name;

private String label;

private TResultSetMetaData metaData;

public String getLabel() {
return label;
}

public void setLabel(String label) {
this.label = label;
}

public TResultSetMetaData getMetaData() {
return metaData;
}

public void setMetaData(TResultSetMetaData metaData) {
this.metaData = metaData;
}

public TBaseModel getModel() {
return model;
}

public void setModel(TBaseModel model) {
this.model = model;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

}

[9] TResultSetMetaData.java

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.user.client.rpc.IsSerializable;

public class TResultSetMetaData implements IsSerializable{

private List columns = new ArrayList();

public List getColumns() {
return columns;
}

public void setColumns(List columns) {
this.columns = columns;
}
}

[10] TestCase.java


public class TestCase {


public TFormQuery getQuery(){
TFormQuery query = new TFormQuery();
query.setName("formQuery");
TDisjuctiveModel model = new TDisjuctiveModel();
model.setName("disjuctiveModel");
query.setModel(model);


TNumberModel nmodel = new TNumberModel();
nmodel.setName("numberModel");
model.getModels().add(nmodel);
// CASE 1
model.setActiveModel(nmodel);

TResultSetMetaData metaData = new TResultSetMetaData();
query.setMetaData(metaData);

TColumn column = new TColumn();
column.setName("c1");
// CASE 2
column.setRenderer(new TExtendedCellRenderer());

query.getMetaData().getColumns().add(column);


return query;

}
}

[11]
http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/4511c86b87d1dbe3/c11d1bf7091bf0d7?q=inheritance+broken&rnum=1#c11d1bf7091bf0d7

[12]
http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/1b29be75d1b47ed/879c8438d50072bc?q=references+list&rnum=1#879c8438d50072bc

georgeuoa

unread,
Jul 5, 2006, 6:12:26 AM7/5/06
to Google Web Toolkit
Let me note that this all refers to Firefox/IE in web mode. My
application doesn't even start in hosted mode...

Eric

unread,
Jul 5, 2006, 6:49:30 AM7/5/06
to Google Web Toolkit

bruciadmin wrote:
> [...] but by not using interfaces,

> how can we provide mocks to the objects which depend on Widgets outside
> hosted mode. Though it is possible to do, a good framework should
> encourage good testability.

You can do mocks without interfaces. Look at EasyMock, and the Mock
Class Extension. http://www.easymock.org/

-eric

ash

unread,
Jul 5, 2006, 6:57:38 AM7/5/06
to Google Web Toolkit
i currently have no time to run up your testcase, but here are my
thoughts.

0. u need to be able to debug ui and serialisation in hosted mode. this
is not an option! there was one defect in the compiler which caused me
to debug the generated javascript in venkman (use -style DETAILED), but
that route takes way longer to solve.

1. i would distill your application into a separate eclipse project. i
actually run 2 different launch clients of my application. one uses
mocks in full hosted mode. this lets me debug the ui. the other binds
to the local tomcat server. change your endpoint to go to the tomcat
server running under eclipse.

2. i would place break points in the ClientSerializationStream class
and step through the marshelling process. obviously u need to know your
object graph and domain model for this.

3. i would place break points in line 220 in the RemoteServiceServlet
class step through the deserialisation process.

im confident that you will find the problem in the
ClientSerializationStream code. i look forward to your fix ;-)

rgds ash

georgeuoa

unread,
Jul 5, 2006, 7:06:37 AM7/5/06
to Google Web Toolkit
Since there is no public code repository, I'm afraid I can't provide
any fix :(

georgeuoa

unread,
Jul 5, 2006, 9:03:57 AM7/5/06
to Google Web Toolkit
Never mind that. What I'm meaning to say is, what you describe might
lead to a solution, but it exceeds my humble capabilities of
understanding. Frankly, you lost me there... so that is for me the main
obstacle of providing a fix, not so much the non existent public
repository.

Now, on the subject, this bug seems to float around for quite some time
now and has incarnated under various personalities. I once stumbled
over [1] reported by sbdy else which is quite easily reproducible with
my test classes when you start sizing them down (remove name
properties, the TResultSetMetaData isn't necessary, you can make the
TFormQuery point immediately to the TColumn). Then the bug I described
goes away, but the one in [1] appears. I traced this a little and it
has to do with reflection: GWT deserialiser correctly guesses the
property and class to set, but sets it on an instance of another class
(ServerSerializationStream:466).

[1]
http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/13eaab5b88e3e198/cf9a1e7f631426f8?q=sun.reflect.UnsafeObjectFieldAccessorImpl&rnum=2#cf9a1e7f631426f8

georgeuoa

unread,
Jul 5, 2006, 10:58:35 AM7/5/06
to Google Web Toolkit
Interestingly enough, the same effect holds when replacing the list
with arrays like TBaseModel[].

Scott Blum

unread,
Jul 5, 2006, 12:44:38 PM7/5/06
to Google Web Toolkit
bruciadmin wrote:
> Of particular note is the lack of usage of interfaces - I understand
> Scott's point a while back that he doesn't see the point of
> instantiating widgets outside hosted mode, but by not using interfaces,
> how can we provide mocks to the objects which depend on Widgets outside
> hosted mode. Though it is possible to do, a good framework should
> encourage good testability.

I think what's preventing me from seeing where your coming from is my
inability to envision the objects you're talking about that depend on
Widgets, yet need to run outside of the GWT environment. In
non-trivial apps I've written, the things that directly interact with
Widgets are very UI specific things that it wouldn't make sense to run
elsewhere. There's typically a View abstraction that the Model talks
to. The View stuff can be independently tested in the GWT environment,
and the Model stuff can be tested in a non-GWT environment with a mock
View. How does what you're doing break this general pattern?

Scott

mme...@google.com

unread,
Jul 5, 2006, 4:12:15 PM7/5/06
to Google Web Toolkit
Hello George,

I apologize for the long delay on this. You are right, there is a bug
relating to cyclic graphs and serializable classes that have
serializable superclasses.

We have a fix for this that will ship in the next release. In the
meantime, here is a work around. (This is not the official fix but it
is a fix that will work and it is easy to communicate.)

The gwt-user.jar file that we shipped with version 1.0.21 includes the
source code for com.google.gwt.user.rpc.ServerSerializationStream which
is where the bug is. If you are willing, you can modify its source and
recompile. Specifically, replace the body of the method "public void
rememberDecodedObject(Object o)" on line 370 from:

public void rememberDecodedObject(Object o) {
fAlreadyDecodedObjects.add(o);
}

to:

public void rememberDecodedObject(Object o) {
if (!fAlreadyDecodedObjects.contains(o)) {
fAlreadyDecodedObjects.add(o);
}
}

This will fix the problem that you are experiencing and it should keep
you moving until we roll out our next release.

bruciadmin

unread,
Jul 5, 2006, 7:57:53 PM7/5/06
to Google Web Toolkit
I had discounted the idea that someone would figure out a way to mock
classes which have contructors which can't actually be invoked. I had
a look at EasyMock, all ready to reply that it wouldn't work, but
you're completely correct, with the class extention version of EasyMock
it worked as normal. Thanks heaps for that - now I've got to find any
other posts I've made about the lack of interfaces and point them
here... humble pie sure could taste better: )

bruciadmin

unread,
Jul 5, 2006, 9:32:18 PM7/5/06
to Google Web Toolkit
Hi Scott,

Thanks for answering. On the topic of unit testing - yes, I'm now
eating humble pie thanks to Eric. It is possible to mock the objects
with EasyMock's class extension.

I still don't agree however with the pattern that any unit testing
using a depenency on Widgets must be done in hosted mode. This
complicates unit testing with implemented Widgets rather then mocks to
validate functionality. If you want to see why people might have
functionality to unit test without wanting to instantiate the Widgets,
I believe breaking down the MVC pattern is required. Looking at the MVC
in the GWT context, the View would be a Widget, the Model would be the
data it represents. From my experience with GWT, Widget's don't get
initialized with a Model which they represent. For example, if I
implement a FlexTable, it doesn't have a FlexModel interface which it
observes. For this reason, when implementing the MVC architecture with
GWT, it becomes necessary to write an object filling the responsibility
of a view which listens to models and when the model updates, receive
that message and update the attached widget. Since GWT does not
implement the View part of MVC completely, we've got to do it
ourselves. And test it. I concede totally that this can be done in
hosted mode, but for true unit testing, we should not have to
instantiate the Widget which our View will update. Again, back to
EasyMock, now we don't have to.

Cheers,

David L

psig...@googlemail.com

unread,
Jul 6, 2006, 3:50:43 AM7/6/06
to Google Web Toolkit
Hi David and Scott,

I'm starting to develop with composites as the controllers of my
widgets (views) and models. The controller knows when to update the
model and after calls widget.paintModel (model);

georgeuoa

unread,
Jul 6, 2006, 4:19:36 AM7/6/06
to Google Web Toolkit
Thank you Miguel for your answer.

Thankfully this is an easy fix to apply, after doing so my test case
indeed works fine.
However, some more complicated graphs I have still come out incorrectly
with references to wrong objects. Do you know of any work around I can
do in my classes (maybe some dummy objects at apropriate places?).

BR
G.

georgeuoa

unread,
Jul 6, 2006, 4:40:37 AM7/6/06
to Google Web Toolkit
For example, I get now things like

Exception while dispatching incoming RPC call
com.google.gwt.user.client.rpc.SerializationException:
java.lang.reflect.InvocationTargetException
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserizeWithCustomSerializer(ServerSerializationStream.java:593)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserialize(ServerSerializationStream.java:516)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.readObject(ServerSerializationStream.java:447)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserializeValue(ServerSerializationStream.java:415)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserializeClass(ServerSerializationStream.java:472)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserializeClass(ServerSerializationStream.java:482)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserialize(ServerSerializationStream.java:523)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.readObject(ServerSerializationStream.java:447)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserializeValue(ServerSerializationStream.java:415)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserializeClass(ServerSerializationStream.java:472)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserialize(ServerSerializationStream.java:523)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.readObject(ServerSerializationStream.java:447)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserializeValue(ServerSerializationStream.java:415)
at
com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:290)
at
com.google.gwt.user.server.rpc.RemoteServiceServlet.doPost(RemoteServiceServlet.java:186)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at
org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:672)
at
org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:463)
at
org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:359)
at
org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:301)
at
org.springframework.web.servlet.mvc.ServletForwardingController.handleRequestInternal(ServletForwardingController.java:139)
at
org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
at
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:45)
at
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:796)
at
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:727)
at
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:396)
at
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:360)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:868)
at
org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:663)
at
org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
at
org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
at
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Thread.java:595)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserizeWithCustomSerializer(ServerSerializationStream.java:576)
... 45 more
Caused by: com.google.gwt.user.client.rpc.SerializationException:
java.lang.reflect.InvocationTargetException
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserizeWithCustomSerializer(ServerSerializationStream.java:593)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserialize(ServerSerializationStream.java:516)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.readObject(ServerSerializationStream.java:447)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserializeValue(ServerSerializationStream.java:415)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserializeClass(ServerSerializationStream.java:472)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserializeClass(ServerSerializationStream.java:482)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserialize(ServerSerializationStream.java:523)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.readObject(ServerSerializationStream.java:447)
at
com.google.gwt.user.client.rpc.core.java.util.ArrayList_CustomFieldSerializer.deserialize(ArrayList_CustomFieldSerializer.java:49)
... 50 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserizeWithCustomSerializer(ServerSerializationStream.java:576)
... 58 more
Caused by: com.google.gwt.user.client.rpc.SerializationException:
java.lang.reflect.InvocationTargetException
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserizeWithCustomSerializer(ServerSerializationStream.java:593)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserialize(ServerSerializationStream.java:516)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.readObject(ServerSerializationStream.java:447)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserializeValue(ServerSerializationStream.java:415)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserializeClass(ServerSerializationStream.java:472)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserializeClass(ServerSerializationStream.java:482)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserialize(ServerSerializationStream.java:523)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.readObject(ServerSerializationStream.java:447)
at
com.google.gwt.user.client.rpc.core.java.util.ArrayList_CustomFieldSerializer.deserialize(ArrayList_CustomFieldSerializer.java:49)
... 63 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserizeWithCustomSerializer(ServerSerializationStream.java:576)
... 71 more
Caused by: java.lang.IndexOutOfBoundsException: Index: 47, Size: 41
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.get(ArrayList.java:322)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.lookupDecodedObject(ServerSerializationStream.java:380)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.prevInstance(ServerSerializationStream.java:363)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.deserialize(ServerSerializationStream.java:488)
at
com.google.gwt.user.server.rpc.ServerSerializationStream.readObject(ServerSerializationStream.java:447)
at
com.google.gwt.user.client.rpc.core.java.util.ArrayList_CustomFieldSerializer.deserialize(ArrayList_CustomFieldSerializer.java:49)
... 76 more

mme...@google.com

unread,
Jul 6, 2006, 9:18:20 AM7/6/06
to Google Web Toolkit
Hello George,

The only change that you could make would be to break the cycles. If
you send me a description of, or the code that generates the
problematic graph, I can see if I can come up with a simple work around
for you for given the version of the code that you have.

holgzn

unread,
Jul 23, 2006, 5:02:18 PM7/23/06
to Google Web Toolkit
I posted a problem with fields not being serialized correctly :
http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/d05ac955a46ad527/a34e35cd14880db6#a34e35cd14880db6
and was directed to this thread.
After i applied the patch, it first seemed to work, but now i sometimes
get InvocationTargetException similar to the one mentioned here, and
also encounterd an IndexOutOfBoundsException from lookupDecodedObject()

I didn't find out which circumstances produce these exceptions, but
it's strange that they appear in such an inpredictable way.

Does anyone know when the next release will come up ? Will it take
days, weeks, months ??
I really would like to get rid of this issue.

georgeuoa

unread,
Jul 24, 2006, 1:57:09 AM7/24/06
to Google Web Toolkit
Hi Holgzn

It is very predictable actually: classes extending other classes,
arrays and references to objects in that array. So smth like this:

Class A;
Class B extends A;

Class C{
A[] someArray;
A someReference;
}

c.someArray[...] = new B();
c.someReference = c.someArray[3]

>From what you wrote I suspect you found an case where the last part is
left out, no references into the array, right? Since it's so a
complicated scenario for the bug to surface, you have actually many
ways of working around:

1. Keep numeric indexes instead of references into the array. So the C
class becomes:

Class C{
A[] someArray;
int indexOfSomeReference;
}

2. If possible (which is probably not) avoid inheritance (it's broken
anyway) and use the concrete types.

3. Split up your RPC call in many smaller: one passing the array,
another the reference, and a third... some other stuff. You just would
have to store the three parts in your HttpSession and make a single
call in the end.

Regards
G.

holgzn

unread,
Jul 24, 2006, 4:57:25 AM7/24/06
to Google Web Toolkit
Thanks again.

The point i don't understand is the following:

I have no extra references pointing to objects inside the Array / List.
I just have the List of Type A with B's and C's. All other fields in
the Object are Integer, String or Boolean.
Of course, there are some Integers that have the same value as Integers
inside the Objects inside the List.
Is that the same for the Serializer ?

I changed all Integer and Boolean fields to their primitives, now.
Currently, it looks like this could help. No errors yet.

Reply all
Reply to author
Forward
0 new messages