If I wrap the contained object in a
java.rmi.MarshalledObject (like JBossMQ does in its ObjectMessage
implementation) it works.
When sending the message:
ObjectMessage message = session.createObjectMessage();
SomeObject obj = new SomeObject( "Parms" );
message.setObject( new MarshalledObject(obj) );
When receiving:
MarshalledObject mobj =
(MarshalledObject)objMessage.getObject();
SomeObject obj
= (SomeObject) mobj.get();
This really seems to be an issue with how
the ClassLoaders are dealt with in JBoss, as it seems this code would not be
completely portable. Is there some better way to work around this
problem?
[Jung , Christoph] Not really, it´s an issue how your
JMS provider´s ObjectInputStream resolves the classes which should be
something like Thread.currentThread().getContextClassLoader().loadClass(...)
(I believe its JBossMQ does so), everything fundamentally different from that
is "stupid moron code" since at least since
JDK1.3.
If you, e.g., look at java.io.ObjectOutputStream (shudder), you
will find a place, where classes are resolved using something like "last
active or defining classloader" in the current stack frame
... implemented via a native method of which at least I have not the
slightest idea of what it does. uuuuuuuaaah.
MarshalledObject, on the other hand, uses a more
sophisticed OutputInputStream to deserialize the object that has
been given in its constructor and uses the right classloader for
resolution.
Go talk to the MQSeries morons ;-) Or make it such
that the Thread.currentThread().getContextClassLoader() is the "last active or
defining classloader" or whatever the SUN guys had in mind when putting their
fingerprints on the keyboard.
CGJ
----- Original Message -----
Sent: Thursday, August 09, 2001 11:02
AM
Subject: [JBoss-dev] Please help:
ClassLoader Confusion
I'm kind of in a bind, and I'm hoping someone
will nudge me in the right direction...
I have MQSeries working quite
well with JBoss (with MDBs and all), but I'm having one problem. When I use
an ObjectMessage, I get an exception on the call to getObject(). The
exception is ultimately a ClassNotFoundException coming out of MQ when it
attempts to deserialize the contained object.
Here's the MQ Series
ObjectMessage implementation that throws the
ClassNotFoundException:
ByteArrayInputStream
bytearrayinputstream = new ByteArrayInputStream(messageBytes, dataStart,
messageBytes.length - dataStart);
ObjectInputStream
objectinputstream = new ObjectInputStream(bytearrayinputstream);
serializable = (Serializable)objectinputstream.readObject();
The
exact same code works perfectly outside of JBoss, and it seems clear that
I'm running into a problem with classloaders. The object contained within
the ObjectMessage is of a type found in my application. This type is used in
many other places in the app (including the sending of the message) and
works fine. The MQ Series classes are located in lib/ext, and since JBoss
gets the connections/sessions started and I'm able to send and receive
messages, they also seem to work fine. It appears that the classloader that
is being used to attempt to deserialize the contained object (the CL that
loaded MQ classes?) cannot see the classes in the app, thus the
ClassNotFoundException. However, the MQ classes have to come from lib/ext
(or another server-level context), since they're used by various mbeans
during startup.
I'm probably overlooking something here, but this
seems to be a catch 22.
This is a build of 2.5 from 7/30.
By
the way, everything's cool if I stuff a String into the
ObjectMessage