[jboss-user] [JBoss Messaging] - Hot deploy of an ear containing a QueueBrowser showing Class

knaas do-not-reply at jboss.com
Tue Jun 10 10:41:19 EDT 2008


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 at a79114{ url=null ,addedOrder=41}".  The classloader of CustomObject prints out as "org.jboss.mx.loading.UnifiedClassLoader3 at 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#4157041

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4157041



More information about the jboss-user mailing list