commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Adam Jenkins <ajenk...@infocomp.com>
Subject Small patch for unusual situation.
Date Mon, 28 Jun 2004 03:06:59 GMT

Hi Guys,

Here's a tiny patch if you want it.  It's for a very limited situation that 
probably only is ever going to affect a small number of developers, however 
I've implemented it in a very non intrusive manner, so it won't impact the 
majority of developers.

The method in question is 
org.apache.commons.lang.SerializationUtils.deserialize(InputStream 
inputStream)

while this is pretty common code using the ObjectInputStream to deserialize 
and object...there is one small drawback with using 
java.io.ObjectInputStream.  When loading the Class for the object you're 
trying to deserialize, java.io.ObjectInputStream gets the classloader from a 
native method called latestUserDefinedLoader().

Now, as far as I can make out...this travels up the stack to get the class 
loader, however, if your code is below the commons-lang code in a classloader 
heirarchy, and exists on it's own classloader, the standard ObjectInputStream 
will throw a class not found exception.

An example.  Say you add common-lang to the tomcat startup classpath...and 
then you deploy a web-app that uses common-lang....and in that web app you 
create a classloader and load an object....and then you try to use the 
SerializationUtils to clone that object (serialize and deserialize)....the 
class loader that will be used will be the tomcat base classloader, and your 
custom loaded code won't be visible.

Now, you would probably never want to do this, I just use it as an example 
because everyone know and understands how tomcat works.  Where you would run 
into this, is if you were writing some kind of container system (with it's 
own classloading components), and had common-lang in the base of it, yet used 
common-lang from within it (down the classloading heirarchy somewhere).

The core change is that ObjectInputStream needs to use 
Thread.getCurrentThread().getContextClassLoader() to resolve the class 
instead of Class.forName(...,..., latestUserDefinedLoader())

Now I know a lot of you are saying..."who the h-e-2*hockey-sticks is going to 
need to do that"...well, me...and I would imagine at least one other person 
has hit a similar situation.

So, not to cause any fuss (this is the non intrusive bit), I created an 
abstract factory to do the creation of ObjectInputStream and, if you don't 
specify a particular env variable, it just gives you the standard 
ObjectInputStream...if you do, it gives you one with resolveClass(...) 
overloaded.

For more detail, see the javadoc.

Sorry no diff...simple change.

Cheers
Adam
Mime
View raw message