5 Replies Latest reply on Nov 23, 2011 10:06 PM by ronorato

    JMS module (HornetQ) can't find my class from WAR

    alex_krasov

      Hi there,

       

      I have an annoying problem here. JMS module (hornetQ) throws a JMSException when trying to deserialize an object whose class is defined at jar that sits inside WAR. It's being failed at findClass of ModuleClassLoader, obviously because the classes sits inside jar that's inside WAR and are being isolated from the hornetQ module...

       

      I can't find a way how I can make this class from inside WAR available to hornetQ module without putting the actual jar with my classes as a resource-root of org.hornetq module (wrong way to do it and rises other problems anyway)...

       

      I'm sure I'm not the first one to have this problem, please help

       

      Thanks.

        • 1. Re: JMS module (HornetQ) can't find my class from WAR
          beve

          Hi,

           

          I'm not sure I've got the full picture of your application. Does your applications consist on a single war, that is it is both producing messages and consuming messages?

           

          I've seen a similar issue but in my case I had an ear, consisting of a war and an ejb. The war posted a ObjectMessage to a queue that an MDB, located in the ejb, listened to. The Object being posted was located in the war.

           

          When the MDB called objMessage.getObject() I got the following exception:

           

          08:16:27,282 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844)) javax.jms.JMSException: se.rl.domain.User from [Module "org.hornetq:main" from local module loader @508aeb74 (roots: /work/jboss/as/as7/jboss-as/build/target/jboss-as-7.1.0.Alpha2-SNAPSHOT/modules)]
          08:16:27,282 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844))         at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:190)
          08:16:27,283 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844))         at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:485)
          08:16:27,283 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844))         at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:444)
          08:16:27,283 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844))         at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:421)
          08:16:27,284 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844))         at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:143)
          08:16:27,284 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844))         at java.lang.Class.forName0(Native Method)
          08:16:27,284 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844))         at java.lang.Class.forName(Class.java:247)
          08:16:27,285 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844))         at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:603)
          08:16:27,285 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844))         at org.hornetq.utils.ObjectInputStreamWithClassLoader.resolveClass(ObjectInputStreamWithClassLoader.java:71)
          08:16:27,286 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844))         at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1574)
          08:16:27,286 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844))         at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495)
          08:16:27,286 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844))         at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1731)
          08:16:27,286 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844))         at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
          08:16:27,287 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844))         at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
          08:16:27,287 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844))         at org.hornetq.jms.client.HornetQObjectMessage.getObject(HornetQObjectMessage.java:158)
          08:16:27,288 ERROR [stderr] (Thread-5 (group:HornetQ-client-global-threads-2068899844))         at se.rl.migrate.mdb.GreeterMDB.onMessage(GreeterMDB.java:42)
          
          

           

          In my case, I was getting this because when trying to locate the class the ThreadContext classloader is first used. The ThreadContext classloader of the mdb module does not have any knowledge of classes in the war, so the code will fallback and try using the 'org.hornetq:main' module and then throw the error displayed above.

           

          I was able to add an explicit dependency from my ejb to my war by adding a manifest header to the ejbs manifest.mf:

           

          Dependencies: deployment.earName.ear.warName.war
          

          This is only for testing and I'd probably extract the objects into a separate jar and add them to the lib directory of the ear.

           

          Not sure if this helps you at all but thought I'd post it just in case.

           

          Regards,

           

          /Daniel

          • 2. Re: JMS module (HornetQ) can't find my class from WAR
            jaikiran

            I believe Daniel already has figured out the real issue. i.e. the classes in the .war are isolated (as per spec) and aren't visible to the MDB (which is in a separate EJB deployment even though the same .ear).

             

            But a side issue here is that the exception stacktrace is misleading (unless one goes and looks into the ObjectInputStream code). That stacktrace gives an impression that it is using a wrong module to load the object's class but doesn't give any indication that it's using that as a fallback mechanism because it failed to resolve that on the first attempt while using the (correct) deployment classloader.

            • 3. Re: JMS module (HornetQ) can't find my class from WAR
              ronorato

              Do I need to do any thing special to get this working if I have my objects in a JAR file that is located in the lib directory of the EAR?  It seems that my webapp (located in a war file inside the ear file) is able to publish events to a HornetQ topic, but my EJB, also located in the ear, is not able to receive the messages.  It fails during the deserialization process.  I see the onMessage getting called which then calls a private method that does the deserialization.  It is in this method that I get the exception.

              • 4. Re: JMS module (HornetQ) can't find my class from WAR
                jaikiran

                ronorato wrote:

                 

                  It seems that my webapp (located in a war file inside the ear file) is able to publish events to a HornetQ topic, but my EJB, also located in the ear, is not able to receive the messages.  It fails during the deserialization process.

                The important part is that the EJB jar will not have access to any classes in the .war. So if the object hierarchy that you are publishing as a ObjectMessage has any reference to such class(es) then it will fail. The right thing to do in such cases is package such classes in a .jar and place them in the .ear/lib so that they are accessible to both the .war and the EJB modules.

                • 5. Re: JMS module (HornetQ) can't find my class from WAR
                  ronorato

                  I add a subscriber to the WAR file for the same topic and it seems to have the same issue.  At this point I am at a loss for how to get this to work.  Here is how I have my project setup. 

                   

                  Here is the EAR manifest:

                  Ant-Version: Apache Ant 1.8.2

                  Created-By: 1.6.0_24-b07 (Sun Microsystems Inc.)

                  Built-By: SCM

                  Specification-Title: App

                  Specification-Version: 0.1

                  Specification-Vendor: Test

                  Implementation-Title: Application

                  Implementation-Version: 0.1 November 23 2011

                  Implementation-Vendor: Application

                  Dependencies: org.slf4j

                   

                  Here is the EAR lib contents (This JAR contains the classes that are serialized onto the JMS):

                  lib/TAppEvent.jar

                   

                  At the root level I have my WAR file and the Jar file containing the EJBs.