JDK-4340158 : Ignoring Thread.getContextClassLoader during ObjectInputStream.readObject
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.io:serialization
  • Affected Version: 1.3.0
  • Priority: P5
  • Status: Closed
  • Resolution: Won't Fix
  • OS: windows_nt
  • CPU: x86
  • Submitted: 2000-05-22
  • Updated: 2000-07-12
  • Resolved: 2000-07-12
Related Reports
Relates :  
Description

Name: skT45625			Date: 05/22/2000


java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)

I am attempting to read an object in a serialized state that is a class that
only exists via a custom class loader (jarLoader in example below).  In
previous versions of Java the only way to do this was to have a special
ObjectInputStream that knew about your external class loader.  As Java2 has the
capability of setting a Thread's context class loader, I assumed that the basic
implementation of ObjectInputStream would now use the custom class loader
rather than the bootstrap (or primordial) class loader.  The reason that it is
important that the base implementation does this is this use case:

Certain web servers deal with failover by serializing objects in the session
(as per the servlet specification).  We want to use dynamically loaded classes
in our application and so we would need the deserialization process to be able
to find the custom class loader.  As we do not have control over the
ObjectInputStream used by the webb server, the default one is all we can use.

Code that illustrates that this does not work:
FileInputStream rawIn = new FileInputStream(new File("someSerializedFile.ser"));
Thread.currentThread().setContextClassLoader(jarLoader);
ObjectInputStream objectIn = new ObjectInputStream(rawIn);
Object o = objectIn.readObject();

This throws a ClassNotFoundException, indicating that the context class loader
is not being referred to.
Stack trace (adjusted):
java.lang.ClassNotFoundException: myLoadedClass
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClassInternal(Unknown Source)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Unknown Source)
        at java.io.ObjectInputStream.resolveClass(Unknown Source)
        at java.io.ObjectInputStream.inputClassDescriptor(Unknown Source)
        at java.io.ObjectInputStream.readObject(Unknown Source)
        at java.io.ObjectInputStream.readObject(Unknown Source)
        at java.io.ObjectInputStream.inputObject(Unknown Source)
        at java.io.ObjectInputStream.readObject(Unknown Source)
        at java.io.ObjectInputStream.readObject(Unknown Source)
        at mycode...
(Review ID: 105152) 
======================================================================

Comments
WORK AROUND Name: skT45625 Date: 05/22/2000 Use my own ObjectInputStream for most cases, but cannot be done in our deployment environment. ======================================================================
11-06-2004

EVALUATION The context class loader mechanism may not work correctly under some circumstances (See bug 4155645 for more details). naveen.sanjeeva@eng 2000-07-11
11-07-2000