12 Replies Latest reply on Jun 27, 2009 6:17 AM by Nikolay Elenkov

    Seam support form message-driven POJO's

    Nikolay Elenkov Master

      I have created a feature request for message-driven POJO's in Seam.
      Please vote if you need/want this as well.


      JBSEAM-4237


      Message-driven POJO's allow you to have asynchronous JMS consumers in your web
      projects, without needing to deploy as EAR and use 'real' MDB's.


      Jencks made this possible a while ago,
      there is also native support in Spring 2.5 (19.4.2. Asynchronous Reception - Message-Driven POJOs).


      Thanks.



        • 2. Re: Seam support form message-driven POJO's
          Nikolay Elenkov Master

          I've been following this thread, but that's eventually about how to use Seam contexts/injections in an MDB.


          The two FR's are similar, but message-driven POJO's (MDP) is about integrating JMS messaging in a
          web application running in Tomcat, for example (no native JMS support in the container).
          Adding the same support as for timers merely provides access to the application context
          and injection, it doesn't deal with registering your listeners, looking up queues, transactions, etc.


          Native support for MDP would involve integrating a message broker and possibly a JCA adapter.
          Check out the Spring link above to see how they have implemented this (and it works quite well, too).


          Of course, this may well be denied, Seam being about using standard technologies and all. We'll see :)

          • 3. Re: Seam support form message-driven POJO's
            Dan Allen Master

            Exactly, what is the point of implementing something that already works? Message-driven beans are about the most POJO classes there are in the Java EE stack (except for maybe entity classes). They implement an interface and implement one method. How hard is that to test?


            Going through the effort of implementing an adapter is really pointless. It's like paving a new road because you don't like the color of the asphalt used to pave the one you are driving on.


            It's one thing to have a managed EntityManager or Transaction because these are APIs that were designed to be used outside of a full EE environment. But a message listener relies on JMS implementation, and since you have to include one you might as well just use the native receiver.

            • 4. Re: Seam support form message-driven POJO's
              Nikolay Elenkov Master

              There are actually two scenarios here:


              1. You are running in full-blown JEE server but your application is deployed as a WAR.
              Some people don't like/use EJB's and are reluctant to redeploy their application
              as an EAR just to get MDB support.


              In this case if you want async messaging, you have to register your JMS listeners
              yourself or do polling (as suggested in the other thread). That mostly works, but
              doesn't support JMS failover, at least not in JBoss 4.2. So yes, it is doable, but
              Seam should make it easy to register your listeners in, say, components.xml.
              Something like:


              <jms:managed-queue-receiver name="myMessageListener" 
                                        auto-create="true" 
                                        queue-jndi-name="queue/myQueue"/>
              



              2. You are running in a web container (Tomcat) and you need async messaging.
              There is no native JMS provider, so you need to integrate one in your app.
              That too is probably doable in Seam by starting, for example,
              ActiveMQ's broker from a postInitialization observer, creating queues using
              ActiveMQ's native API's and hooking up listeners 'by hand'. Getting your
              listeners to be transactional is probably trickier, but still should be doable
              as well. 


              The point of integrating this in Seam is, as with most things, to save you
              from writing boilerplate code, so you can concentrate on your actual application.
              So one would have something like this in their components.xml and
              possibly just switch the broker implementation if they moved to a 'real'
              application server.


              <jms:broker name="broker" class="ActiveMQBroker" brokerName="localhost" start="true"/>
                   
              <jms:connectionFactory name="connectionFactory" brokerURL="${activemq.brokerUrl}" />
              



              And, no, I don't thinks MDB's (in JEE 5) are hard to test, on the contrary. What is
              hard to test is async processing, but that's a different story.


              JMS was designed to be used outside of a container as well (J2EE 1.3 did not require a JMS provider),
              so requiring a full-blown app server just to get JMS is a bit too much.


              So, to sum this up, I am not saying reimplement JMS because I don't like it, I am saying
              make it easier to integrate in Seam applications in both full JEE and web-only containers.


              • 5. Re: Seam support form message-driven POJO's
                Arbi Sookazian Master

                Nikolay Elenkov wrote on Jun 12, 2009 04:26:


                There are actually two scenarios here:

                1. You are running in full-blown JEE server but your application is deployed as a WAR.
                Some people don't like/use EJB's and are reluctant to redeploy their application
                as an EAR just to get MDB support.


                2. You are running in a web container (Tomcat) and you need async messaging.



                1. most likely to be rejected: use an EAR (EJB is not a disease!)


                2. this is a better (more valid) argument/requirement...



                Most Web servers do not offer JMS as a standard feature, but it is simple enough to add a JMS implementation to a Web server environment.

                source: http://www.javaworld.com/javaworld/jw-01-2008/jw-01-tomcat6.html?page=3

                • 6. Re: Seam support form message-driven POJO's
                  Nikolay Elenkov Master

                  Arbi Sookazian wrote on Jun 12, 2009 08:38:


                  1. most likely to be rejected: use an EAR (EJB is not a disease!)



                  I do use EAR's, but sometimes it is not that easy. Say you have an application, deployed
                  as a WAR, and later on you have new requirements, so you need to add JMS. It may not be
                  so easy (or even possible) to switch to an EAR that late in development/support. Being able
                  to (easily) add an async message listener without changing your application structure is a
                  desirable flexibility. You might still switch to an EAR in your next major version, but you
                  may need JMS now.



                  2. this is a better (more valid) argument/requirement...

                  Most Web servers do not offer JMS as a standard feature, but it is simple enough to add a JMS implementation to a Web server environment.

                  source: http://www.javaworld.com/javaworld/jw-01-2008/jw-01-tomcat6.html?page=3



                  Well, SpringSource is betting everything on Tomcat, so they have deemed it enterprise-ready :)
                  It is indeed possible to add JMS support to Tomcat, but I would not say it is 'simple'. You may
                  require transactions, message persistence and other features, so not really that simple.



                  • 7. Re: Seam support form message-driven POJO's
                    Arbi Sookazian Master

                    Your argument for WAR is valid, but you could simply always package and deploy an EAR instead of WAR and thus prevent the problem from happening...


                    I'm not sure how Tomcat is enterprise-ready if it doesn't support distributed tx's, for example.  For that, you need JTA which typically means JBoss AS or equivalent...


                    I think you're better off with Spring/Hibernate/Tomcat if you don't want or need EJB components...

                    • 8. Re: Seam support form message-driven POJO's
                      Leo van den berg Master

                      I just want to support the easier integration support. I especially like Nikolay's comment about having a simple listener definition in components.xml. It's all about that, use your sparse resources for developing the business requirements and not in writing boilerplate code.


                      Seam has numerous goodies such as Excel, PDF, email support so why not a keyboard-saver for JMS and to be honest messaging (such as JMS) is a fundamental part for ANY large scale enterprise application.


                      Leo

                      • 9. Re: Seam support form message-driven POJO's
                        Arbi Sookazian Master

                        well, it's just another goodie possibly in Seam 3...

                        • 10. Re: Seam support form message-driven POJO's
                          Dan Allen Master

                          You bring up some good points, notably that you want to be able to take advantage of JMS when using a WAR project. The main issue is that there is no standard API for registering a JMS listener that is not an MDB, so Seam would have to provide a configurable component like you suggested that accepts the class of the broker. I suppose this could be implemented and if it were, it would give you guaranteed delivery w/o MDB.


                          As for wanting to use MDB inside of a WAR, that will be possible soon in JBoss AS and in general part of the Java EE standard. In fact, I think you can do it today with GlassFish V3 (I can't confirm whether it's ready yet). Java EE 6 features simplified packaging (the rise of the WAR as I call it) so EJBs can be packaged in a WAR.


                          The argument I really don't get is the requires a full-blown application server. Take Tomcat, at JTA, JCA and JMS to it and what exactly do you have? Pretty much the same thing as an application server. And with the Java EE 6 web profile, it really isn't different from Tomcat at all (except that it doesn't have blatant holes in it). I agree with you that in the past (and perhaps still a bit true today) a Java EE application server had too much in it, but I don't buy the argument that it is too heavy any more (and looking ahead to JBoss AS 6 and GlassFish V3).


                          I get Leo's point, though, that Seam's JMS support doesn't have enough goodies. So assuming that the JMS server is running somewhere, it would be cool to have a declarative way to catch the message and delegate it on to another component. I'm pretty booked at the moment so likely I can't undertake the research project, but if someone wants to give it a shot we can certainly roll it into Seam if it looks good.

                          • 11. Re: Seam support form message-driven POJO's
                            Nikolay Elenkov Master

                            Dan Allen wrote on Jun 13, 2009 00:53:


                            The main issue is that there is no standard API for registering a JMS listener that is not an MDB, so Seam would have to provide a configurable component like you suggested that accepts the class of the broker. I suppose this could be implemented and if it were, it would give you guaranteed delivery w/o MDB.



                            MessageConsumer is a standard API, you can create one once you get a hold of a Session. Still there should be some Seam component(s)
                            to manage its creation and/or lifecycle.




                            As for wanting to use MDB inside of a WAR, that will be possible soon in JBoss AS and in general part of the Java EE standard. In fact, I think you can do it today with GlassFish V3 (I can't confirm whether it's ready yet). Java EE 6 features simplified packaging (the rise of the WAR as I call it) so EJBs can be packaged in a WAR.



                            I know Java EE 6 is just around the corner, and will be all better, but still it will be sometime before we can use it for
                            'real' projects. Some people are quite conservative in what is 'allowed' for a production system. And sometimes this choice
                            is made for you. I am not saying that's the way it should be, it's just the way it is :) So, yes, JEE 6 is cool, but we need
                            something that works on JEE 5.



                            The argument I really don't get is the requires a full-blown application server. Take Tomcat, at JTA, JCA and JMS to it and what exactly do you have? Pretty much the same thing as an application server. And with the Java EE 6 web profile, it really isn't different from Tomcat at all (except that it doesn't have blatant holes in it). I agree with you that in the past (and perhaps still a bit true today) a Java EE application server had too much in it, but I don't buy the argument that it is too heavy any more (and looking ahead to JBoss AS 6 and GlassFish V3).



                            As I said, you are not always free to use the latest and greatest technologies. And look at JBoss 5 (JEE 5 compliant), it was released
                            only 6 months ago. We might expect that a stable, JBoss-supported JEE 6 stack will take sometime. So 'the past' will be with us for a little while more. Btw, Tomcat-ActiveMQ is way faster (startup) and smaller (memroy footprint) than any JBoss.


                            Don't get me wrong here, I would use the latest stacks and 'full-blown' AS's, when given the choice, but that is not always the case.



                            I get Leo's point, though, that Seam's JMS support doesn't have enough goodies. So assuming that the JMS server is running somewhere, it would be cool to have a declarative way to catch the message and delegate it on to another component. I'm pretty booked at the moment so likely I can't undertake the research project, but if someone wants to give it a shot we can certainly roll it into Seam if it looks good.


                            I will give it try, and post a patch and a simple example for the first case (no JMS provider integration). If that eventually gets accepted,
                            I might try the second one as well. I will probably not be able to test it extensively (on different JMS providers), though.


                            • 12. Re: Seam support form message-driven POJO's
                              Nikolay Elenkov Master

                              I've attached a patch to the JIRA that covers the first case (listening for messages and delegating to a Seam component).
                              It uses JNDI and the AS messaging provider, so only works in 'real' JEE servers (no Tomcat).


                              Details in the JIRA, but here's how you basically use it:


                              components.xml:
                              
                              <jms:async-message-listener-container
                                  auto-create="true" startup="true" name="jmsContainer"
                                  destination-jndi-name="queue/A"
                                  listener="#{myListener}"
                                  exception-listener="#{myListener}"
                                  outjected-session-name="myListenerSession" /> 
                              



                              Please try it out. Any comments are welcome.