0 Replies Latest reply on Jun 10, 2008 10:41 AM by Keith Naas

    Hot deploy of an ear containing a QueueBrowser showing Class

    Keith Naas Newbie

      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!