7 Replies Latest reply on Feb 27, 2016 4:01 PM by George Berish

    How to get the HornetQ API to my ear application on Wildfly?

    George Berish Novice

      I'm being totally defeated in my effort to move a simple test application (deployed as an ear package) from dead Glassfish to WildFly 9. I hope someone can offer any advice.

       

      Here's my problem:

       

      The WildFly log clearly shows my Message Driven Bean's onMessge(Message msg) method receives an ObjectMessage sent by my Java Client (A Java Swing GUI running outside any container)

       

      Then the Wildfly Log confirms that msg.getClass().getSimpleName() returns HornetQObjectMessage.

       

      But when I try to cast msg to HornetQObjectMessage (so I can extract the object)the WildFly Log says:

      Caused by: java.lang.NoClassDefFoundError: org/hornetq/jms/client/HornetQObjectMessage at org.america3.gotest.server.messaging.GoMsgBean.onMessage(GoMsgBean.java:123)

       

      I can see  org/hornetq/jms/client/HornetQObjectMessage.class in this jar:

      <WildFlyHome>\modules\system\layers\base\org\hornetq\main\hornetq-core-client-2.4.7.Final.jar

      So I know its there.

       

      Everything I find says my problem is I need to force WildFly's class loader to load dependencies for my application.  In this case I think that means alerting WildFly to the fact my application needs the org.hornetq module.

       

      But I can't find anywhere that shows me how to do that.

       

      I tried adding this module I got from Oracle

      <?xml version="1.0" encoding="UTF-8"?>

      <module xmlns="urn:jboss:module:1.1" name="org.acmemq">

          <dependencies>

             <!-- we depend on org.hornetq module since we will send messages to  -->

             <!-- the HornetQ server embedded in the local WildFly instance       -->

             <module name="org.hornetq" />

          </dependencies>

      </module>

       

      Then I modified the module's name to be my package name - GoTest.ear.  (But I'm still struggling to get a grip on dependencies so it was just a guess.)

      <?xml version="1.0" encoding="UTF-8"?>

      <module xmlns="urn:jboss:module:1.1" name="GoTestEar">

          <dependencies>

                 <module name="org.hornetq" />

          </dependencies>

      </module>

       

      And the error remains.

       

      Can anyone offer any help on how to get the class loader to make HornetQObjectMessage available to my application?   (Other than packaging a jar that contains it with my application.  Note: My Java client already uses the WildFly jar above to send its ObjectMessage as a HornetQObjectMessage.

        • 1. Re: How to get the HornetQ API to my ear application on Wildfly?
          Justin Bertram Master

          Can you elaborate on why exactly you need to cast your message to the implementation object?  If you need to extract your object from the message why don't you just cast it to javax.jms.ObjectMessage and invoke getObject()?

          • 2. Re: How to get the HornetQ API to my ear application on Wildfly?
            George Berish Novice

            In my Java client I used JNDI lookup("jms/RemoteConnectionFactory") to get a ConnectionFacory, and discovered what I received was a HornetQJMSConnectionFactory.

             

            Then I went through the normal old JMS API to get to a Session.

             

            Then found createObjectMessage() from the Session that flowed from that factory created a HornetQObjectMessage.

             

            Which my WildFly log confirm is what arrived at onMessage (Message msg) in my MDB.

             

            I did try casting msg to ObjectMessage, but I guess HornetQObjectMessage can't be cast that way.

             

            So to get my object, I need to cast Message msg -> HornetQObjectMessage objMsg.

             

            Maybe there is a diffierent ConnectionFactory, but since WildFly natuarlly delivers HornetQ, I'd like to not rely on a workaround.

             

            Besides, if I'm going to bite the bullet and move everything over to WildFly 9, I need to be able signal WildFly when an app is dependent on jars it already has to avoid any future version mismatches.

             

            Thank you for any help.  This is killing me.

            • 3. Re: How to get the HornetQ API to my ear application on Wildfly?
              Justin Bertram Master

              In my Java client I used JNDI lookup("jms/RemoteConnectionFactory") to get a ConnectionFacory, and discovered what I received was a HornetQJMSConnectionFactory.

              The JMS API is just that - an API.  It's a bunch of interfaces that have to be implemented.  HornetQ provides a JMS implementation, and anytime you look at a JMS object in a debugger or print out the class type it will be a HornetQ implementation object.  However, you shouldn't need to use the implementation objects themselves.  You should just be able to use the interfaces.

               

              Then found createObjectMessage() from the Session that flowed from that factory created a HornetQObjectMessage.

              That's the expected behavior, of course.

               

              I did try casting msg to ObjectMessage, but I guess HornetQObjectMessage can't be cast that way.

              Why not?  org.hornetq.jms.client.HornetQObjectMessage implements javax.jms.ObjectMessage so it should be castable.  Do you get an error if you attempt to cast it?

               

              So to get my object, I need to cast Message msg -> HornetQObjectMessage objMsg.

              I still don't understand why you must cast to an implementation object rather than the JMS interface.

               

              Maybe there is a diffierent ConnectionFactory, but since WildFly natuarlly delivers HornetQ, I'd like to not rely on a workaround.

              I'm not sure what you mean here.  Can you elaborate on what different connection factory you think may exist?

               

              You should work to avoid using implementation objects whenever possible as it makes your code less portable.  In fact, the JMS implementation has changed between Wildfly 9 and 10 so any code you write that depends on JMS implementation objects in Wildfly 9 will have to be changed in Wildfly 10.  To reiterate, it shouldn't be necessary to use implementation objects at all unless you're doing something implementation specific which by all accounts you aren't.

              • 4. Re: How to get the HornetQ API to my ear application on Wildfly?
                Justin Bertram Master

                BTW, if you want to know more about adding dependencies to your deployment (e.g. your EAR file) then I recommend reading the documentation.

                • 5. Re: How to get the HornetQ API to my ear application on Wildfly?
                  George Berish Novice

                  Hi Justin,

                   

                  I  can only imagine how frustrating it is for someone who knows as much as you do to try helping someone who doesn't know it all yet.

                   

                  But it felt a bit condescending that you assumed that having a question at this level -- JMS and J2EE deployment and WildFly -- didn't mean I at least know it's a good idea to avoid implementation instances whenever possible.

                   

                  I mean that's why I was careful in my explanation to say I tried Casting Message msg to ObjectMessage oMsg and WildFly saw it as an error. 

                   

                  However based on your certainty,  I'll try again this weekend to redo everything to see I can get an ObjectMessage out of my client and to the MDB given that my lookup returned an object I could only make work when I Cast it to HornetQConnectionFactory. If so I'll post it here for those who follow.  It is true that transferring to WildFly throws so many curves, you never know when working around and earlier one will trip you up later.

                   

                  For those who find this posting in the future because they encounter my dependency problem, all I can tell them is your advice  -- "read the literature"  -- seems to be the universal response by others like yourself who seem to think communicating an app's dependency on already existing modules is too trivial to take seriously. 

                   

                  In case it holds any interest, you are the fourth to throw out "read the literature" ... Grin ... I guess that's because we all know WildFly's documentation is wonderfully clear and complete.  But so far none has taken the simpler route of just offering a simple example of code that works ... or pointing to where "in the literature" that exists.. 

                   

                  Everything I could find says all it takes is to use module.xml to add an existing module's resources to an app.  I can see the org.hornetq module exists, and it has the client jar I wanted for my app.  But if there's an example of a simple module.xml that communicates any app's dependency on any existing module I can't find it.

                   

                  Therefore, if one exists that communicates a dependency of any app on any existing module, I know I'd appreciate getting it out from behind the "just read the literature" shield whose use seems to entertain high end WildFly/JBoss.  And I bet many other users driven from Oracle's abandoned Glassfish would as well. 

                   

                  So if anyone else out there is willing to point to where "in the literature"  there's an explanation with example, it would be nice.

                   

                  Otherwise, thank you again for your attempt to help. 

                  If I succeed in redoing all code from scratch I'll post it here next week.

                  • 6. Re: How to get the HornetQ API to my ear application on Wildfly?
                    Justin Bertram Master

                    I apologize if my previous comment came off as condescending.  I'm honestly just trying to help.  If my comment was terse please know it was for lack of time rather than disregard for you or your question.  I try to help users on the forum when I can but oftentimes other responsibilities get in the way.  To be clear, I've worked with lots of users who have significantly different backgrounds so I try not to assume too much.  I was just trying to be helpful and let you know that the JMS implementations changed recently so it was especially important to avoid implementation objects.

                     

                    I mean that's why I was careful in my explanation to say I tried Casting Message msg to ObjectMessage oMsg and WildFly saw it as an error.

                    In your previous comment you said, "I did try casting msg to ObjectMessage, but I guess HornetQObjectMessage can't be cast that way."  You didn't elaborate on what exactly the problem was (error or not).  My point simply was that org.hornetq.jms.client.HornetQObjectMessage implements javax.jms.ObjectMessage so it should be castable.  If you're getting an error when you attempt to make this cast then let's deal with that rather than trying to use implementation objects.

                     

                    For those who find this posting in the future because they encounter my dependency problem, all I can tell them is your advice  -- "read the literature"  -- seems to be the universal response by others like yourself who seem to think communicating an app's dependency on already existing modules is too trivial to take seriously.

                    The documentation I linked previously is pretty well-written in my opinion.  I say that as someone who doesn't work on Wildfly and who has consulted the documentation to understand how things work.  There are several ways to accomplish what you want and to go through the various options would just reproduce the documentation.  I think the information you're looking for is in the "EAR Class Loading" section.  Also, the documentation has overall classloading information that is likely important for your use-case (e.g. the fact that each deployment is considered a module, that certain dependencies are established automatically, etc.).  The bottom line here is that you really should read the documentation to understand how to solve your problem because it's not as simple as "turn knob x to value y."  I can't speak for others you've worked with, but my recommendation wasn't the equivalent of "RTFM."

                     

                    In any event, I think your bottom line issue is the apparent failure to cast org.hornetq.jms.client.HornetQObjectMessage to javax.jms.ObjectMessage.  It seems to me that you're run into all the other problems in an attempt to solve this one.  If possible, I think it would be best to go back to this original issue and try to solve that.

                    • 7. Re: How to get the HornetQ API to my ear application on Wildfly?
                      George Berish Novice

                      Hi Justin,

                       

                      You were right.  When  I redid the client from scratch sticking with Java interfaces the problem went away.  I guess somewhere in my frustrating first try to get from GlassFish to WildFly I convinced myself the only way to work around a prior error was casting things to their HornetQ version.

                       

                      So I'll save the issue of how to tell the class loader my app depends on modules already there somewhere else for another day.

                       

                      I'm sure it will be a useful thing to know when deploying future applications, since I have some that in Eclipse are already dependent on classes defined in other applications.

                       

                      But for now.  Thank you.  All is better.  Well as better as it can be when first confronting WildFly.