JBM rocks by the way. This is the first big issue we have encountered in months of usage.
We have an application with a QueueBrowser that consumes from a JBM queue that at this
point contains only ObjectMessages. The ObjectMessage contains a basic custom class that
is part of the ear. The first time the application is deployed, messages are browsed
correctly from the queue. After a hot deploy, we can no longer browse the queue.
I am not very familiar with the internals of JBM, but here is what I found while
debugging. We are using JBoss 4.2 with JBM 1.4.0-SP3-CP01.
This is the code:
| //various setup code for the session all within a try/finally that ultimately
closes the QueueBrowser, QueueSession, and QueueConnection
| final Enumeration enumerator = browser.getEnumeration();
| while (enumerator.hasMoreElements())
| {
| final ObjectMessage message = (ObjectMessage) enumerator.nextElement();
|
| final Object messageObject = message.getObject();
|
| if (messageObject instanceof CustomObject)
| {
| // code path on a fresh server
| }
| else
| {
| // code path after a redeploy
| }
| }
|
1. After a redeploy the messageObject is a CustomObject, but its from a dead ClassLoader
(likely the undeployed ear). I think it's dead because when I print it out, it says
"org.jboss.mx.loading.UnifiedClassLoader3@a79114{ url=null ,addedOrder=41}".
The classloader of CustomObject prints out as
"org.jboss.mx.loading.UnifiedClassLoader3@fff327{
url=file:/C:/jboss/jboss-4.2/server/default/tmp/deploy/tmp31717application.ear
,addedOrder=43}". This explains why the else state executes.
2. On a fresh start of the server, if I debug into the "message.getObject()"
call, it eventually lands in MessageSupport.getPayload(), which because the payload is
null and the payloadAsByteArray is not, goes into StreamUtils.readObject. Eventually the
object is deserialized and returned to the client.
3. On a redeploy, when I debug into the "message.getObject()" method, it lands
in MessageSupport.getPayload() but now the payload is not null and the payloadAsByteArray
is null. It returns the payload that is associated to the dead classloader immediately.
It seems like a cached Message is being returned, one that was previously deserialized
with the original deployed ear's ClassLoader. And since it is a different
ClassLoader, we end up with the invalid codepath being following.
I could probably code up a workaround that uses reflection to process the Message's
object.
Any thoughts as to what is happening?
Is there a way to override the cached payload behavior?
Is there additional work that can be down to shutdown the QueueBrowser/QueueSession such
that the Queue is reset to the original state?
Thanks!
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4157041#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...