Hi all,
I'm playing around with class loaders, and I seem to be having some
problems. Suppose that I write my own class loader, like so:
///////////////////////////////////////////
import java.io.*;
public class StreamClassLoader extends ClassLoader
{
public StreamClassLoader()
{
}
private static byte[] readData( final InputStream inStream,
final int length )
throws IOException
{
final byte[] data = new byte[ length ];
int readSoFar = 0;
while( readSoFar < length )
{
readSoFar += inStream.read( data, readSoFar, length -
readSoFar );
}
return data;
}
private Class loadClass( final String expectedClassName,
final byte[] classData )
{
return defineClass( classData, 0, classData.length );
}
public Class loadClass( final String expectedClassName, final
InputStream inStream, final int length )
{
return loadClass( expectedClassName, readData( inStream, length ) );
}
}
///////////////////////////////////////////
Now, if I want to use this class loader, I can't just use Class.forName(
String ), as it will just use the default loader. Instead, I have to do
something like:
StreamClassLoader loader = new StreamClassLoader();
Class someClassType = loader.loadClass( "some.ClassType" );
Okay, I can live with that. But the problem is that if I am reading objects
off of an ObjectInputStream, it uses the default class loader.
Interestingly, an ObjectOutputStream does
not need the class loader to write an object of this type. I assume that it
just uses the object's class directly.
So my question is: how do I link the custom class loader to an
ObjectInputStream? It would also be nice get Class.forName(...) to work
also, so that other parts of the code would not have to know about the
custom loader.
Thanks,
Dave.
Matthias Ernst - 20 Oct 2003 10:28 GMT
> So my question is: how do I link the custom class loader to an
> ObjectInputStream? It would also be nice get Class.forName(...) to work
> also, so that other parts of the code would not have to know about the
> custom loader.
It is good practice for any class that finds classes by name, such as
factories, object deserializer, ... to use the current thread's {@link
Thread#getContextClassLoader context classloader}. I think
ObjectInputStream complies to that, so the solution would be:
ClassLoader old = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(streamLoader);
try {
return ois.readObject();
} finally {
Thread.currentThread().setContextClassLoader(old);
}
Matthias

Signature
Matthias Ernst
Software Engineer
CoreMedia - Smart Content Technology