CRC problem in serialization

85 views
Skip to first unread message

Ian

unread,
Sep 26, 2006, 5:09:26 PM9/26/06
to Google Web Toolkit
Hello,

I'm trying to build an application using JBoss for the back end and GWT
for the front end. For some reason, I'm getting an exception on
deserialization. I debugged the problem using the Venkman debugger in
Mozilla and found that _methodMap contains an entry for

my.package.PressVO/4075102973

but the _typeSignature passed to _instantiate15 is

my.package.PressVO/1622132682

Since there's no entry in _methodMap for the given _typeSignature,
_instantiate15 immediately calls _raiseSerializationException.

I have spent time stepping through the serialization and
deserialization code and I discovered that the number following the
type name is some kind of CRC of the source code for the named class.
The thing is, I don't understand why this CRC would be different
between client and server--I'm sure that the same code is being
referenced in both places.

What should I check next? It seems like I could turn off the CRC
checking, but I don't know how or if it's a good idea. Would it help
to post some example code?

Thanks,
Ian

Miguel Méndez

unread,
Sep 27, 2006, 9:14:21 AM9/27/06
to Google-We...@googlegroups.com
Hello Ian,

The CRC serves as a type signature.  We use it to detect incompatibilities in a class' definition between the client and the server.  (This can happen if modify one of your RPC types, then roll out a new version of your server but you still have old clients in the field.)  It is possible to disable this feature but it is generally a bad idea.

The question is why would the server and client's class definitions be "different"?  If you could post some sample code that shows this in JBoss, I'd be happy to look into it.

Thanks,
--
Miguel

Ian

unread,
Sep 27, 2006, 1:33:41 PM9/27/06
to Google Web Toolkit
Thanks for the reply Miguel.

I _think_ I've found the problem, but I have yet to confirm it for
myself.

I believe I'm running into problems with the various class loaders in
JBoss.

My class hierarchy is as follows:

my.package.vo.ReflectiveVO
+- my.package.vo.PressVO
+- my.package.ejb.entities.Press

ReflectiveVO is the base class for all of my entities (entities as
defined by EJB3.0) and the VOs I use to send data back to the GWT
client. Inside ReflectiveVO is some machinery that makes it possible
to iterate over the fields of a given entity without using Java-style
reflection. (We built this machinery to make the GWT client a little
easier to write.)

PressVO subclasses ReflectiveVO and defines the layout of a "press"
entity. It has a bunch of static final members that specify the
various fields in a press and it also defines all the various getters
and setters.

Press subclasses PressVO and adds EJB3.0-style annotations to make
Hibernate (within JBoss) happy.

I discovered recently that it is possible to create a
PressVO_CustomFieldSerializer to customize how GWT serializes instances
of PressVO, so I also have a PressVO_CustomFieldSerializer. In
debugging the server-side serialization process, I discovered that, at
some point, GWT asks if there is a cutom serializer for the current
instance. When "the current instance" is a PressVO, I expect the
answer to be "yes", but the answer is "no".

I _think_ the reason for this odd response is that the PressVO class
was loaded by a UnifiedClassLoader3, but the
PressVO_CustomFieldSerializer class was loaded by a WebappClassLoader.
So, when GWT asks for the public static void
serialize(SerializationStreamWriter, PressVO), the answer is "no such
method" because the class loaders are different and it doesn't
recognize the PressVO parameter as being the right kind of parameter.

This type mismatch is only detectable at runtime because, at compile
time, there is no classloader to consider and an object's type is fully
determined by its fully qualified class name. Therefore, I think the
GWT compiler generates a type signature for PressVO that takes into
account the custom serializer, but the GWT runtime is generating a
signature that does _not_ include a custom serializer and there's a
mismatch at the time of deserialization.

I have decided to try refactoring my class hierarchy to see if it gets
me around this problem. Rather than having Press inherit from PressVO,
I'm going to make Press and PressVO share a common interface but be
otherwise unrelated. I expect that this will force PressVO to be
loaded by the WebappClassLoader instead of the UnifiedClassLoader3 and
the GWT runtime will then recognize my custom serializer and things
will be great again.

I'll post to this thread again when I know the results of my
experiment.

Ian

PS Can I suggest that the GWT server-side runtime generate some kind of
warning or exception if it finds a class named
Foo_CustomFieldSerializer that doesn't have the requisite methods? I
_know_ my PressVO_CustomFieldSerializer has the right methods on it so
a warning (or exception) saying that it didn't might have led me to the
source of the problem more quickly.

Marcos Araujo Sobrinho

unread,
Sep 27, 2006, 7:46:57 PM9/27/06
to Google-We...@googlegroups.com
Hi Ian, hi Miguel.

I think that I´m having a similar problem but i´m using a simpler hierarchy without CustomFieldSerializer.

I´m getting the following exception in JBoss:

Exception while dispatching incoming RPC call
com.google.gwt.user.client.rpc.SerializationException: java.lang.ClassNotFoundException: No ClassLoaders found for: br.com.ymf.cadastroAlcada.client.vo.Alcada
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.deserialize(ServerSerializationStreamReader.java:147)
at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader.readObject(AbstractSerializationStreamReader.java:59)
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.deserializeValue(ServerSerializationStreamReader.java:61)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:249)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.doPost(RemoteServiceServlet.java:147)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
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.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175)
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74)
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:869)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
at java.lang.Thread.run(Thread.java:534)
Caused by: java.lang.ClassNotFoundException: No ClassLoaders found for: br.com.ymf.cadastroAlcada.client.vo.Alcada
at org.jboss.mx.loading.LoadMgr3.beginLoadTask(LoadMgr3.java:212)
at org.jboss.mx.loading.RepositoryClassLoader.loadClassImpl(RepositoryClassLoader.java:511)
at org.jboss.mx.loading.RepositoryClassLoader.loadClass(RepositoryClassLoader.java:405)
at java.lang.ClassLoader.loadClass(ClassLoader.java:235)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:302)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:219)
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.deserialize(ServerSerializationStreamReader.java:126)
... 24 more

...
...
...

The Alcada class is very simple:

public class Alcada implements IsSerializable {
private String codigo;
private String nome;
private String descricao;
private int status;

public String getCodigo() {
return codigo;
}

public void setCodigo(String codigo) {
this.codigo = codigo;
}

public String getDescricao() {
return descricao;
}

public void setDescricao(String descricao) {
this.descricao = descricao;
}

public String getNome() {
return nome;
}

public void setNome(String nome) {
this.nome = nome;
}

public int getStatus() {
return status;
}

public void setStatus(int status) {
this.status = status;
}

public String[] toArray() {
return new String[]{codigo, nome, ""+status,descricao};
}
}

...
...
...

And everything works just *fine* when the VO is populated and serialized on the server, and de-serialized on the client (JAVA->JS). I only get the exception when I try to send the VO from the client to server (JS->JAVA).

Any suggestions?

Marcos

-----Mensagem original-----
De: Google-We...@googlegroups.com
[mailto:Google-We...@googlegroups.com]Em nome de Ian
Enviada em: quarta-feira, 27 de setembro de 2006 14:34
Para: Google Web Toolkit
Assunto: Re: CRC problem in serialization

Miguel Méndez

unread,
Oct 2, 2006, 9:40:31 AM10/2/06
to Google-We...@googlegroups.com
Hello Ian & Marcos,

It seems that there are several issues relating to JBoss integration.  Specifically,
I suspect that these most likely trace back to the classloader issue that Ian has pointed out in this thread .  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 any of you have additional information please send it my way.  (A simple JBoss enabled project that demonstrates the problem would be greatly appreciated.)

Thanks,

On 9/27/06, Marcos Araujo Sobrinho <MSob...@ymf.com.br> wrote:

Hi Ian, hi Miguel.

I think that I´m having a similar problem but i´m using a simpler hierarchy without CustomFieldSerializer.

I´m getting the following exception in JBoss:

Exception while dispatching incoming RPC call
com.google.gwt.user.client.rpc.SerializationException: java.lang.ClassNotFoundException: No ClassLoaders found for: br.com.ymf.cadastroAlcada.client.vo.Alcada
        at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.deserialize(ServerSerializationStreamReader.java:147)
        at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamReader.readObject (AbstractSerializationStreamReader.java:59)
        at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.deserializeValue(ServerSerializationStreamReader.java:61)
        at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall (RemoteServiceServlet.java:249)

        at com.google.gwt.user.server.rpc.RemoteServiceServlet.doPost(RemoteServiceServlet.java:147)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:173)

        at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java :202)
        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.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175)
        at org.jboss.web.tomcat.security.JaccContextValve.invoke (JaccContextValve.java:74)

        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:869)
        at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
        at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket (PoolTcpEndpoint.java:527)

        at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
        at java.lang.Thread.run(Thread.java:534)
Caused by: java.lang.ClassNotFoundException : No ClassLoaders found for: br.com.ymf.cadastroAlcada.client.vo.Alcada
        at org.jboss.mx.loading.LoadMgr3.beginLoadTask(LoadMgr3.java:212)
        at org.jboss.mx.loading.RepositoryClassLoader.loadClassImpl(RepositoryClassLoader.java :511)
        at org.jboss.mx.loading.RepositoryClassLoader.loadClass(RepositoryClassLoader.java:405)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:235)
        at java.lang.ClassLoader.loadClassInternal (ClassLoader.java:302)

        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:219)
        at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.deserialize (ServerSerializationStreamReader.java:126)



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