tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Christopher Schultz <ch...@christopherschultz.net>
Subject Re: session de-serialization issue
Date Sun, 07 Dec 2008 14:49:42 GMT
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Tom,

Tom Mader wrote:
> It appears that if I try to store a class in the session that contains
> anything other than native JDK types, I get a de-serialization error when
> the session is loaded after tomcat restarts.

There are several reasons this can happen. I'll try to describe some of
them.

> public class TestClass implements Serializable {

[snip]

> I can put this class directly into the session and it is successfully
> serialized and de-serialized across tomcat restarts.  This is working just
> fine.

Good.

> However, if I create a containing class for my simple class:
> 
> public class ContainingClass implements Serializable {

[snip]

> I receive the following error upon de-serialization after tomcat restarts:
> 
> 5-Dec-08 7:02:14 PM org.apache.catalina.session.StandardManager doLoad
> SEVERE: IOException while loading persisted sessions:
> java.io.InvalidClassException: invalid field type for testClass in class
> ContainingClass
>    at java.io.ObjectInputStream.readClassDescriptor(libgcj.so.7rh)

This generally happens when you have modified the definition of
TestClass and had an object of the old definition already serialized.
You can demonstrate this yourself by doing the following:

1. Create a class (TestClass). Write a quick program to create a new
object then serialize it. Write another (separate) program to
de-serialize that object from a file. Verify everything works.

2. Change TestClass by re-arranging some of the method signatures.
Re-compile everything. Try re-running your de-serializer against the
previously-serialized TestClass object: you'll get the above error.

When you compile a Java class, the compiler looks for a "static long"
member called "serialVersionUID". If that hasn't been defined, it will
generate one for you by hashing a bunch of stuff together to create
something relatively unique. That number is supposed to uniquely
identify the version of the class, and it gets stored with serialized
objects. When you modify the class, the auto-generated version id
changes, and the old, serialized object doesn't match the version of the
new class.

One technique is to manually set this serialVersionUID. Another is to
simply not change the class when you want to read old versions of it. I
suspect what happened was:

1. You created the class and put an object into a session.
2. You changed the class and recompiled, resulting in a webapp reload.
   Reloads trigger session persistence.
3. The new class was loaded into the new webapp.
4. Your stale object was loaded and didn't match the new class version.

If you delete your SESSIONS.ser file, can you persist your new objects?

As much as Chuck hates gjc, I don't think this is the culprit in this
particular case. Gjc has lots of other problems WRT running web
applications, but this shouldn't be one of them.

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkk74oYACgkQ9CaO5/Lv0PDshgCgr1ThBOT0akYdgiwoEyhefQs5
yocAn0MIwIHJqd3guDNQTeFcFurc28YO
=JIQ0
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Mime
View raw message