12 Replies Latest reply on Feb 7, 2007 6:07 PM by Gavin King

    MDB's and EJB Timers

    Bradley Smith Master

      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

        • 2. Re: MDB's and EJB Timers
          Bradley Smith Master

          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
            Bradley Smith Master

            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
              Pete Muir Master

               

              "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 Master

                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
                  Bradley Smith Master

                  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 Master

                    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
                      Bradley Smith Master

                      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
                        Pete Muir Master

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

                        • 10. Re: MDB's and EJB Timers
                          Bradley Smith Master

                          doh!

                          Thanks! ;-)

                          • 11. Re: MDB's and EJB Timers
                            Bradley Smith Master

                            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 Master

                              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.