Bug 48007 - ClassNotFoundException when deserializing custom object with FileStore
Summary: ClassNotFoundException when deserializing custom object with FileStore
Alias: None
Product: Tomcat 5
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 5.5.27
Hardware: PC Linux
: P2 normal (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
Depends on:
Reported: 2009-10-15 14:55 UTC by mmalaidini
Modified: 2010-08-13 10:25 UTC (History)
1 user (show)


Note You need to log in before you can comment on or make changes to this bug.
Description mmalaidini 2009-10-15 14:55:33 UTC
We're using the FileStore to make sessions persistent. Sessions are serialized correctly, but every minute or so we get an exception like the following:

SEVERE: Session: 6D026DD0479F48B331D28EE8325095BB;
java.lang.ClassNotFoundException: com.whatever.spikes.session.CustomClass
       at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
       at java.security.AccessController.doPrivileged(Native Method)
       at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
       at java.lang.ClassLoader.loadClass(ClassLoader.java:319)
       at java.lang.ClassLoader.loadClass(ClassLoader.java:254)
       at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:399)
       at java.lang.Class.forName0(Native Method)
       at java.lang.Class.forName(Class.java:247)
       at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:604)
       at org.apache.catalina.util.CustomObjectInputStream.resolveClass(CustomObjectInputStream.java:78)
       at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1575)
       at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1496)
       at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1732)
       at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
       at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
       at org.apache.catalina.session.StandardSession.readObject(StandardSession.java:1407)
       at org.apache.catalina.session.StandardSession.readObjectData(StandardSession.java:931)
       at org.apache.catalina.session.FileStore.load(FileStore.java:296)
       at org.apache.catalina.session.StoreBase.processExpires(StoreBase.java:194)
       at org.apache.catalina.session.PersistentManagerBase.processExpires(PersistentManagerBase.java:553)
       at org.apache.catalina.session.ManagerBase.backgroundProcess(ManagerBase.java:664)
       at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1285)
       at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1570)
       at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1579)
       at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1579)
       at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1559)
       at java.lang.Thread.run(Thread.java:637)

This doesn't happen if we put CustomClass in $CATALINA_HOME/shared/lib or $CATALINA_HOME/shared/classes

<Context path="/Spikes" reloadable="true" docBase="/Users/mman/Workspaces/Spikes" workDir="/Users/mman/Workspaces/Spikes/work" >
       <Manager className="org.apache.catalina.session.PersistentManager" maxIdleBackup="0" >
               <Store className="org.apache.catalina.session.FileStore" directory="/Users/mman/tmp/tomcat-sessions"/>

*) Mac OS/X 10.6.1
*) JDK 1.6.0_15
*) Tomcat 5.5.27
Comment 1 mmalaidini 2009-10-15 14:57:18 UTC
Check thread http://marc.info/?l=tomcat-user&m=125553788214052&w=2 at tomcat-user
Comment 2 kserwin 2009-11-02 08:38:30 UTC
Same behavior observed when using tomcat 6.0.14 and 6.0.20.
Is there any workaround for this problem?
Comment 3 Mark Thomas 2010-01-12 14:51:52 UTC
Correcting version as per issue description
Comment 4 Mark Thomas 2010-02-02 07:06:23 UTC
This works for me with a simple test web application.

Re-reading your description and the users thread, it suggests the object has been created in one application but is being read by another. This is not a valid use case. This would explain why using the shared class loader allows this to work.

If this isn't your use case, please feel free to re-open this bug and attach the simplest possible web application (with source) that demonstrates the issue so it can be investigated further.
Comment 5 Konstantin Kolinko 2010-02-02 07:41:12 UTC
Are you running with a SecurityManager enabled?

Note, that
1. org.apache.catalina.util.CustomObjectInputStream.resolveClass(..)
does two attempts to load a class.

First with webapp classloader, then with some other classloader (see ObjectInputStream.resolveClass(...), ObjectInputStream.latestUserDefinedLoader()).

The exception that is logged comes from the second attempt.

2. webapp classloader throws ClassNotFoundException when java.security.AccessControlException is encountered when loading a class
Comment 6 Konstantin Kolinko 2010-03-09 15:20:55 UTC
I changed exception handling in CustomObjectInputStream#resolveClass(..) in trunk r920912 and proposed for 6.0 and 5.5.
If you will be able to reproduce this issue, please let us know.
Comment 7 Konstantin Kolinko 2010-03-10 22:29:04 UTC
Exception handling fix applied to 5.5, will be in 5.5.29 onwards.
Comment 8 Scott Hamilton 2010-08-13 10:25:44 UTC
I came across the code change for this (http://svn.apache.org/viewvc?view=revision&revision=920912) doing some pre-upgrade analysis and am wondering what information from the first exception (that was being hidden until this change) was more useful than the secondary exception?  We've got a similar class in our application to accomplish the same basic goal and are considering doing the same fix to our class but want to understand the benefit/impact a little more.

The community might benefit from this info being attached to this record as well (thus I'm posting here rather than in a forum area).