You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Adam Jenkins <aj...@infocomp.com> on 2004/06/28 05:06:59 UTC

Small patch for unusual situation.

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

Re: Small patch for unusual situation.

Posted by "matthew.hawthorne" <ma...@apache.org>.
Adam Jenkins wrote:
> Sorry, just realized there is 'System.out' code which will need to be 
> removed...email me if you want me to rip it out.  (didn't use a logger due to 
> classloading isolation testing requirements :) ).


You should submit this as an enhancement in Bugzilla, so it doesn't get 
lost.

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: Small patch for unusual situation.

Posted by Adam Jenkins <aj...@infocomp.com>.
Sorry, just realized there is 'System.out' code which will need to be 
removed...email me if you want me to rip it out.  (didn't use a logger due to 
classloading isolation testing requirements :) ).

On Mon, 28 Jun 2004 01:06 pm, Adam Jenkins wrote:
> 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


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org