12 Replies Latest reply on Feb 7, 2007 6:07 PM by gavin.king

    MDB's and EJB Timers

      Hello,

      Is it possible to have Seam intercept the onMessage(...) invokations of an MDB and honor the @In, @Logger annotations?

      Also, same question for session beans with @Timeout methods - is it possible to have Seam do the same for methods marked @Timeout?

      Thanks,
      Brad Smith

        • 1. Re: MDB's and EJB Timers
          pmuir
          • 2. Re: MDB's and EJB Timers

            that's not really an answer to my question.

            http://docs.jboss.com/seam/1.1.1.GA/reference/en/html_single/#d0e2525

            says the same thing but our experience is that @In does not get honored for the onMessage() calls by the container.

            So.... my question(s) still stand. We've actually tried this stuff. What we found is that we had to use EJB3 annotations to inject references to our session beans, and then, when we invoked methods on our session beans, Seam did successfully intercept and @Inject resources to the session beans. Seam @In (@Logger) did not work for the MDB itself; same is true for @Timeout methods in other session beans.

            Thanks,
            Brad Smith

            • 3. Re: MDB's and EJB Timers

              BTW - we generally do scan the docs, examples, this forum, and a bit of Googling before we post questions here.

              • 4. Re: MDB's and EJB Timers
                pmuir

                 

                "bsmithjj" wrote:
                says the same thing but our experience is that @In does not get honored for the onMessage() calls by the container


                Sorry, just trying to help you out :( Dunno about the Timeout stuff, no experience of that.

                I did some work with a message driven bean for receiving emails and, as I said, @In did work for me. I've just taken a look at the code (unfortunately its in pieces at the moment) I had I seem to have used @Logger (and it was certainly writing out log messages).

                If you post the MDB you are trying to get working I'll check it against what I have?

                • 5. Re: MDB's and EJB Timers
                  gavin.king

                  For MDBs, yes, that works.

                  For @Timeout methods, unfortunately, IIRC, the EJB spec says that they do not get intercepted (which is extremely annoying). So what you can try to do is to use a Seam asynchronous method instead.

                  • 6. Re: MDB's and EJB Timers

                    One thing I have realized digging into this issue more is that the EJB Deployer is immediately deploying my EJB jar. The MDB gets started immediately thereafter. If messages are on the Q the MDB is listening to, then it starts trying to consume them.... I think that maybe the Seam infrastructure, which AFAIK is bootstrapped by the war, is not available to listen to the MDB lifecycle, and thus, the Seam annotations are causing exeptions or are null on startup.

                    Is there any suggestion for how to deal with this?

                    Thanks,
                    Brad Smith

                    • 7. Re: MDB's and EJB Timers
                      gavin.king

                      This could make sense, I suppose. I guess its kinda wrong that MDBs in the ejbjar should go live before the rest of the EAR is fully started. Report this as a bug to the EJB3 team, if it is truly the case....

                      I suppose I could make my interceptor throw exceptions if seam is not fully started ... but eeeeew.....

                      • 8. Re: MDB's and EJB Timers

                        other item, @Logger doesn't ever seem to work for MDB's.

                        @MessageDriven(
                         activationConfig = {
                         @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
                         @ActivationConfigProperty(propertyName = "destination", propertyValue = "java:/SonicJMS/Queues/AccessControl/Receive"),
                         @ActivationConfigProperty(propertyName = "providerAdapterJNDI", propertyValue = "java:/SonicJMSProvider"),
                         @ActivationConfigProperty(propertyName = "useDLQ", propertyValue = "false")
                         }
                        )
                        public class TestDriverMDB implements MessageListener {
                        
                         //private Log log = LogFactory.getLog(TestDriverMDB.class);
                        
                         @Logger
                         private Log log;
                        
                         @Resource MessageDrivenContext context;
                        
                         public void onMessage(Message message) {
                         if (log == null) {
                         context.setRollbackOnly();
                         LogFactory.getLog(TestDriverMDB.class).info("Seam Logger has not been set - rolling back.");
                         } else {
                         log.info("onMessage() : message -> " + message);
                         try {
                         TextMessage textMessage = (TextMessage) message;
                         if (textMessage == null) {
                         log.info("message was null?");
                         } else {
                         log.info(textMessage.getText());
                         }
                         } catch (ClassCastException e) {
                         log.warn("message was not an instance of TextMessage.");
                         } catch (JMSException je) {
                         log.error(je, je);
                         context.setRollbackOnly();
                         }
                         }
                         }
                        }
                        


                        And what happens after the application has fully deployed/started and a message arrives on the Q:

                        10:59:37,918 INFO [ChannelSocket] JK: ajp13 listening on /0.0.0.0:8009
                        10:59:37,950 INFO [JkMain] Jk running ID=0 time=0/79 config=null
                        10:59:37,950 INFO [Server] JBoss (MX MicroKernel) [4.0.4.GA (build: CVSTag=JBoss_4_0_4_GA date=200605151000)] Started in 1m:25s:425ms
                        11:00:22,998 INFO [TestDriverMDB] Seam Logger has not been set - rolling back.
                        11:00:22,998 INFO [TestDriverMDB] Seam Logger has not been set - rolling back.
                        11:00:22,998 INFO [TestDriverMDB] Seam Logger has not been set - rolling back.
                        11:00:22,998 INFO [TestDriverMDB] Seam Logger has not been set - rolling back.
                        11:00:22,998 INFO [TestDriverMDB] Seam Logger has not been set - rolling back.
                        11:00:23,013 INFO [TestDriverMDB] Seam Logger has not been set - rolling back.
                        11:00:23,013 INFO [TestDriverMDB] Seam Logger has not been set - rolling back.
                        11:00:23,013 INFO [TestDriverMDB] Seam Logger has not been set - rolling back.
                        .....
                        ....... REPEATS A LOT ......
                        .....
                        11:00:27,841 INFO [TestDriverMDB] Seam Logger has not been set - rolling back.
                        11:00:27,841 WARN [MDB] JMS provider failure detected:
                        javax.jms.JMSException: Connection dropped
                         at progress.message.jimpl.JMSExceptionUtil.createJMSException(Unknown Source)
                         at progress.message.jimpl.aw.handleMessage(Unknown Source)
                         at progress.message.zclient.MessageHandler.deliverToClient(Unknown Source)
                         at progress.message.zclient.wx.MEC_(Unknown Source)
                         at progress.message.zclient.wx.LEC_(Unknown Source)
                         at progress.message.zclient.MessageHandler.ZO_(Unknown Source)
                         at progress.message.zclient.xd.xR_(Unknown Source)
                         at progress.message.zclient.xd.dispatchLocalEnv(Unknown Source)
                         at progress.message.zclient.Connection.connectionDropped(Unknown Source)
                         at progress.message.zclient.Connection.NRB_(Unknown Source)
                         at progress.message.zclient.DefaultDropHandler.socketDropped(Unknown Source)
                         at progress.message.zclient.Connection.PRB_(Unknown Source)
                         at progress.message.zclient.ClientSender.ep_(Unknown Source)
                         at progress.message.zclient.ClientSender.threadMain(Unknown Source)
                         at progress.message.zclient.DebugThread.run(Unknown Source)
                        11:00:27,841 INFO [MDB] Trying to reconnect to JMS provider
                        11:00:27,857 ERROR [STDERR] [106] progress.message.client.ENotConnected: An open connection has not been established
                        11:00:27,857 ERROR [STDERR] at progress.message.zclient.Session.publish(Unknown Source)
                        11:00:27,857 ERROR [STDERR] at progress.message.jimpl.QueueReceiver.makeGetRequest(Unknown Source)
                        11:00:27,857 ERROR [STDERR] at progress.message.jimpl.aspi.wd.handleMessage(Unknown Source)
                        11:00:27,857 ERROR [STDERR] at progress.message.zclient.MessageHandler.doNextWorkItem(Unknown Source)
                        11:00:27,857 ERROR [STDERR] at progress.message.zclient.lx.threadMain(Unknown Source)
                        11:00:27,857 ERROR [STDERR] at progress.message.zclient.DebugThread.run(Unknown Source)
                        11:00:27,873 INFO [STDOUT] Exception in thread ClientSender $CONNECTION$ Administrator: java.lang.NullPointerException
                        11:00:27,873 INFO [STDOUT] null
                        11:00:27,873 ERROR [STDERR] java.lang.NullPointerException
                        11:00:27,873 ERROR [STDERR] at progress.message.msg.v26.DefaultPayload.AD_(Unknown Source)
                        11:00:27,873 ERROR [STDERR] at progress.message.msg.v26.DefaultPayload.fD_(Unknown Source)
                        11:00:27,873 ERROR [STDERR] at progress.message.msg.v26.DefaultPayload.writeToStream(Unknown Source)
                        11:00:27,873 ERROR [STDERR] at progress.message.msg.v26.Mgram.writePayloadToStream(Unknown Source)
                        11:00:27,873 ERROR [STDERR] at progress.message.msg.v26.Mgram.writeMgramToStream(Unknown Source)
                        11:00:27,873 ERROR [STDERR] at progress.message.msg.v26.Mgram.writeMgramToNetworkStream(Unknown Source)
                        11:00:27,873 ERROR [STDERR] at progress.message.msg.v26.MgramCreator.St_(Unknown Source)
                        11:00:27,873 ERROR [STDERR] at progress.message.msg.v26.MgramCreator.secureDeliver(Unknown Source)
                        11:00:27,873 ERROR [STDERR] at progress.message.zclient.ClientSender.threadMain(Unknown Source)
                        11:00:27,873 ERROR [STDERR] at progress.message.zclient.DebugThread.run(Unknown Source)
                        


                        • 9. Re: MDB's and EJB Timers
                          pmuir

                          You need an @Name on the MDB to make it Seam component.

                          • 10. Re: MDB's and EJB Timers

                            doh!

                            Thanks! ;-)

                            • 11. Re: MDB's and EJB Timers

                              after @Naming my MDB's as Seam components:

                              2007-02-07 11:40:03,215 ERROR [org.jboss.jms.asf.StdServerSession] session failed to run; setting rollback only
                              java.lang.RuntimeException: java.lang.IllegalStateException: Attempted to invoke a Seam component outside the context of a web application
                               at org.jboss.ejb3.interceptor.LifecycleInterceptorHandler.postConstruct(LifecycleInterceptorHandler.java:109)
                               at org.jboss.ejb3.EJBContainer.invokePostConstruct(EJBContainer.java:582)
                               at org.jboss.ejb3.AbstractPool.create(AbstractPool.java:108)
                               at org.jboss.ejb3.ThreadlocalPool.get(ThreadlocalPool.java:48)
                               at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:54)
                               at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
                               at org.jboss.ejb3.mdb.MDB.localInvoke(MDB.java:865)
                               at org.jboss.ejb3.mdb.MDB.localInvoke(MDB.java:844)
                               at org.jboss.ejb3.mdb.MDB$MessageListenerImpl.onMessage(MDB.java:1074)
                               at org.jboss.jms.asf.StdServerSession.onMessage(StdServerSession.java:266)
                               at progress.message.jimpl.Session.dU_(Unknown Source)
                               at progress.message.jimpl.Session.run(Unknown Source)
                               at org.jboss.jms.asf.StdServerSession.run(StdServerSession.java:196)
                               at EDU.oswego.cs.dl.util.concurrent.PooledExecutor$Worker.run(PooledExecutor.java:743)
                               at java.lang.Thread.run(Thread.java:595)
                              Caused by: java.lang.IllegalStateException: Attempted to invoke a Seam component outside the context of a web application
                               at org.jboss.seam.contexts.Lifecycle.getServletContext(Lifecycle.java:413)
                               at org.jboss.seam.contexts.Lifecycle.beginApplication(Lifecycle.java:89)
                               at org.jboss.seam.Seam.componentForName(Seam.java:228)
                               at org.jboss.seam.intercept.SessionBeanInterceptor.postConstruct(SessionBeanInterceptor.java:101)
                               at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                               at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                               at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                               at java.lang.reflect.Method.invoke(Method.java:585)
                               at org.jboss.ejb3.interceptor.LifecycleInvocationContextImpl.proceed(LifecycleInvocationContextImpl.java:131)
                               at org.jboss.ejb3.interceptor.LifecycleInterceptorHandler.postConstruct(LifecycleInterceptorHandler.java:105)
                               ... 14 more
                              


                              I posted a message at http://www.jboss.com/index.html?module=bb&op=viewtopic&t=100946 - hopefully that's a reasonable place to post it.

                              • 12. Re: MDB's and EJB Timers
                                gavin.king

                                This would definitely happen if the MDB started to process messages before the WAR had finished starting up. Like I said above, that would be a bug in our appserver, IMO.