8 Replies Latest reply on Jun 9, 2009 9:06 AM by Leo van den berg

    Seam, JMS (ActiveMQ) & Hibernate

    Osian Hughes Newbie

      Hi,


      First let me explain my situation:


      On a remote machine, a JMS Object message is produced, containing a specific Hibernate DAO, and is posted onto a queue in ActiveMQ.  Then, on the web side, i.e. Seam, I have a Session scoped Seam component which is also a javax.jms.MessageListener, and this then updates some local values when a new message is received.  This all works fine, but then I have a problem when I want to start using a Hibernate session.  Firstly, the session is injected into the component properly, but then when the onMessage method is called, the session has been set to null, and I can't use Component.getInstance for this either because it complains that there is 'No active application context'.


      Does anyone have any ideas of how to get around this one??


      I can also post some code if required.


      Thanks in advance,
      Osian

        • 1. Re: Seam, JMS (ActiveMQ) & Hibernate
          Osian Hughes Newbie

          Anyone any thoughts on this problem?


          Note I am also using icefaces for the UI, therefore when a new JMS message arrives, the screen is updated without any user interaction required, so should the onMessage perform some sort of submit to wake up the SEAM side of things?


          Osian

          • 2. Re: Seam, JMS (ActiveMQ) & Hibernate
            Joshua Davis Expert

            You meant DTO, not DAO, right?


            The reason your MessageListener doesn't work is that the Seam/JSF lifecylce isn't happening on that thread.


            I have an application that does something similar.  Rather than making a MessageListener, I simply pull messages off the JMS destination using MessaegConsumer.receive whenever the browser polls the server.


            Since your browser must be polling the server for changes, you must have some backing bean method that is called periodically.   Just receive messages until there aren't any more, and then process them with the Hibernate session, etc.

            • 3. Re: Seam, JMS (ActiveMQ) & Hibernate
              Osian Hughes Newbie

              Hi Joshua,


              Thanks for the reply.


              What I meant with DAO are the hibernate data access objects, i.e. what is mapped from the DB through hibernate into objects.


              Anyway, with Icefaces, there is the possibility to push changes from the server to the browser without the need for the user to interact, therefore you get a real-time feel to the application, which is what I need with the JMS messages, i.e. a real-time kind of dashboard display that can be active 100% of the time without any interaction required.


              And unfortunately, the design of the system doesn't allow me to use the receive method for this part of the UI, because it is a topic that I am subscribing to, not a message queue.


              You mention the Seam/JSF lifecycle, Is there any way to invoke the Seam lifecycle from the java code when I receive and need to process a message? i.e. imitate a user action.


              Thanks again,


              Osian

              • 4. Re: Seam, JMS (ActiveMQ) & Hibernate
                Joshua Davis Expert

                Osian Hughes wrote on May 28, 2009 14:03:


                Hi Joshua,

                Thanks for the reply.

                What I meant with DAO are the hibernate data access objects, i.e. what is mapped from the DB through hibernate into objects.


                So you mean a Java object with Hibernate mappings?  That's an entity.  A DAO (Data Access Object) usually contains logic that retrieves / updates entities using a Hibernate session.



                Anyway, with Icefaces, there is the possibility to push changes from the server to the browser without the need for the user to interact, therefore you get a real-time feel to the application, which is what I need with the JMS messages, i.e. a real-time kind of dashboard display that can be active 100% of the time without any interaction required.


                Yes.  My application has the exact same requirement.  While we don't use IceFaces, the concept is the same: the browser must poll the server for updates periodically.  Even if you haven't written any code to do it, something has to be doing it.   HTTP doesn't allow the server to push to the browser, period.


                We solved the problem using Seam Remoting and JavaScript (IceFaces/Ajax4Jsf were too slow).  The JavaScript calls a Seam component over and over.   The Seam component receives any messages, loads objects using Hibernate, and sends the data back to the browser.   The rest of the JS dynamically updates the DOM based on the data.


                You should be able to do the same thing with IceFaces.




                And unfortunately, the design of the system doesn't allow me to use the receive method for this part of the UI, because it is a topic that I am subscribing to, not a message queue.


                Topic/Queue doesn't matter.   My application uses a topic to broadcast market information.   A conversation-scoped backing bean subscribes to the topic when the page is loaded, then the polling loop calls a method picking up any messages on that subscription.



                You mention the Seam/JSF lifecycle, Is there any way to invoke the Seam lifecycle from the java code when I receive and need to process a message? i.e. imitate a user action.


                You'd have to make a separate object as the MessageListener, because you want Seam to inject / outject / intercept your component before you call the methods on the component.  This message listener is running on a separate thread, which may cause other issues.


                I don't recommend this because it's just not necessary.   IceFaces must have some JavaScript in the browser that is polling the server.   Use your backing bean to subscribe to the topic and figure out what methods are being called repeatedly.   Pick up messages inside that method and you're done.

                • 5. Re: Seam, JMS (ActiveMQ) & Hibernate
                  Osian Hughes Newbie

                  Hi Joshua,


                  Sorry for the late reply, but I was pulled away from the project for some customer bugs that needed fixing :)


                  Thanks for your reply.


                  The way that I had written the backing beans for the seam component handling the messages is:
                    I have a session scoped seam component called alarmHandler which extends HibernateEntityHome and initialises a MessageListener and starts it
                    Then when the MessageListener implementation receives a new JMS Message, it updates the required values and pushes the change back to the UI


                  But as I said earlier this doesn't seem to be working very well, i.e. the Hibernate session seems to be getting closed and not re-opened on subsequent uses of HibernateEntityHome.getSession().


                  I can post some of the code if that would help, but I am interested in the JS and SeamRemoting solution you mention.  Do you have some sample code, or some pointers that could help me?


                  Thanks again,
                  Osian

                  • 6. Re: Seam, JMS (ActiveMQ) & Hibernate
                    Leo van den berg Master

                    Hi Osian,


                    We just had a similar discussion in


                    http://seamframework.org/Community/JMSMessageListenerInAWebApplication


                    And the basic message is that you don't have access to Seam components from within onMessage (I am sure the Seam experts will have a solution for this(. The thing we did was to use the Quartz timer service which has full access to Seam components and make that call the topic to see if theer are new messages.


                    It is not a beautifull solution, but it works for the time being. We need the JMS sevice because we want to have all connected users see the same status of a list of traffic incidents. We have considred the Ajax/JMS solution, but it present status (see the warning in the docs) and the fact that you are downgrading a highly reliable service as JMS made us decide not to use the script solution.


                    As mentioned in the other thread, we would like to see a comparable solution for JMS as is provided for Quartz.


                    Leo





                    • 7. Re: Seam, JMS (ActiveMQ) & Hibernate
                      Nikolay Elenkov Master

                      Leo van den Berg wrote on Jun 08, 2009 13:36:


                      As mentioned in the other thread, we would like to see a comparable solution for JMS as is provided for Quartz.



                      Well, you should file a JIRA if you want to see a solution in Seam. Btw, the Quartz/async stuff is in
                      org.jboss.seam.async.Asynchronous and friends, so it should be fairly easy to port it to JMS.


                      And Seam support for message-driven POJO's would be nice as well (as in Spring and Jencks), so while you are at it,
                      you could file a JIRA for that too :)