Solution and root of problem:

My application was using ObjectInputStream (OIS) to convert a serialized instance of an object. OIS uses a different class loader, one which does not have visibility of the classes loaded in the WebappClassLoader. This was giving a ClassNotFoundException.

Then I found CustomObjectInputStream. Initially, I tried to import this from catalina.jar but this caused several errors on deploying the war, mainly related to XML parsers (??).

I then got the source for CustomObjectInputStream and added it to my web-app (about 100 lines of code). This yielded a solution, full credit to... Craig R. McClanahan and Bip Thelin for writing this :-)

Thanks to those who replied to my earlier question.

regards,
Peter

On 01/22/2013 07:16 PM, Peter Lavin wrote:

Hi again,

I've spent some time on this today and have found (at least I think so)
that my problem in deserializing an instance of an object is related to
the ClassLoader that the class ObjectInputStream uses. It appears that
it does not use the WebappClassLoader of the service in question, but
instead defaults to a ClassLoader higher up the tree (which does not
have visibility on the cache of the WebappClassLoader).

In my service, I've loaded a full class definition and created an
instance of it. At this point it (afaik) must be in the cache of the
WebappClassLoader. However, when an ObjectInputStream is called to...
ois.readObject() on a byte[] of an instance of that same class, it fail
for ClassNotFoundException.

A Tomcat solution is identified here...
http://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/util/CustomObjectInputStream.html


Which is in $CATILANA_HOME/lib/catalina.jar.

Has anyone use this? do I need to add this jar implement this, and
include it in my war file?

regards,
Peter




On 01/21/2013 08:30 PM, Konstantin Kolinko wrote:
2013/1/21 Peter Lavin<lav...@cs.tcd.ie>:

Dear List,

My web application needs to deserialize both classes and objects
which are
sent to it.

I'm using Base64 serialization, and when I transport full<name>.class
file
to a service, I can deserialize it with no problem using
ObjectInputStream.readObject(). I also need to transport instances of
certain classes to the application but without having the benefit of
having
the class loaded in the WebappClassLoader. Not surprisingly,
deserializing
an instance of a class fails for ClassNotFoundException.

My question: When I need to transport an instance of a class, I can
easily
also transport the full class. This full class can be instantiated if
required. How could I load this class to the WebappClassLoader and
have it
available there for when I need to call ois.readObject()? I want to
load the
(full) class to the WebClassLoader to over come the
ClassNotFoundException.


The same as with any other ClassLoader:
use the bytes and call ClassLoader.defineClass(..), then
ClassLoader.resolveClass(..).

There is an example in WebappClassLoader.clearReferencesJdbc() method
(though resolveClass() is not called there, I do not know why - maybe
it was just forgotten).

Env:
Tomcat 7.0.14

Known security issues:
http://tomcat.apache.org/security-7.html

OSCentOS release 5.8 (Final)
java version 1.6.0 22
OpenJDK Runtime Environment (IcedTea6 1.10.10)
(rhel-1.28.1.10.10.el5 8-x86 64)
OpenJDK 64-Bit Server VM (build 20.0-b11, mixed mode)


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org



--
with best regards,
Peter Lavin,
PhD Candidate,
CAG - Computer Architecture & Grid Research Group,
Lloyd Institute, 005,
Trinity College Dublin, Ireland.
+353 1 8961536

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to