14 Replies Latest reply on Jan 25, 2011 3:15 AM by nickarls

    What's wrong with transactional CDI events?

    eugene-71

      I created very simple testcase to try CDI events in JBoss 6 Final. It works OK if attribute "during" of "Observers" annotation set to TransactionPhase.IN_PROGRESS. But if "during" set to any other value, method listen() doesn't called and JBoss writes to console: {code}20:55:40,700 ERROR [org.jboss.weld.Event] WELD-000401 Failure while notifying an observer of event er.t2.TestEvent@78a17a{code} Source code: {code:java} // TestEvent.java public class TestEvent {      private String message;

       

           public TestEvent(String message) {

               this.message = message;

           }

       

           public String getMessage() {          return message;

           }

      } // T2Remote.java @Remote public interface T2Remote {      void theTest(); } // T2Bean.java @Stateless public class T2Bean implements T2Remote

      {      @Inject

           private Event<TestEvent> events;

       

           @Override      public void theTest() {

               events.fire(new TestEvent("from bean " + System.currentTimeMillis()));

           }

      }

       

      // TestListener.java

      @Stateless

      public class TestListener {

           public void listen( @Observes(during=AFTER_COMPLETION) TestEvent evt ) {

               System.out.println("Event: " + evt.getMessage());

           }

      }

      {code}

       

      What's wrong?

        • 1. What's wrong with transactional CDI events?
          nickarls

          After completion of what transaction? Have you tried it at a point where you have a persistence context that commits?

          • 2. Re: What's wrong with transactional CDI events?
            eugene-71

            I guess, by default, trasaction is always present on business method call...

             

            Well, I added persistence unit which uses local-tx datasource (embedded hsqldb):

             

             

            @Stateless
            public class TestSB implements TestSBRemote
            {
                @PersistenceContext(unitName="testPU")
                private EntityManager em;
            
                @Inject
                private Event<TestEvent> events;
            
                @Override
                public List<Account> getAccounts() 
                {
                    TypedQuery<Account> q = em.createQuery( "SELECT a FROM Account a", Account.class );
                    List<Account> lst = q.getResultList();
                    return lst;
                }
            
                @Override
                public void put() 
                {
                    Account a = new Account();
                    a.setAccount("zzz");
                    em.persist(a);
                    em.flush();
                    events.fire(new TestEvent("from bean " + System.currentTimeMillis()));
                }
            }     
            

             

            On put() method, transaction completes successfully, database comitted, but JBoss shows same error (WELD-000401) and method listen( @Observes(during=AFTER_COMPLETION) TestEvent evt ) not called.

            • 3. Re: What's wrong with transactional CDI events?
              nickarls

              ...and I just recalled that even if there would be no transaction, the event would still be fired in synch.

               

              Tried without the remote interface?

              • 4. Re: What's wrong with transactional CDI events?
                nickarls

                Tried a simple stateless -> stateless transactional event and it appears to be working (see attachment)

                • 5. Re: What's wrong with transactional CDI events?
                  eugene-71

                  Nicklas Karlsson wrote:


                  Tried without the remote interface?

                   

                  Just tried... Replaced remote interface with local, inject in servlet and call... Same result. ((

                  • 6. What's wrong with transactional CDI events?
                    eugene-71

                    Nicklas Karlsson wrote:

                     

                    Tried a simple stateless -> stateless transactional event and it appears to be working (see attachment)

                     

                    Tested...

                    Looks like, it work if EJB called from web application, which contains beans.xml.

                     

                    And doesn't work in case of remote call. Well, then events rather useless for me. ((

                     

                    Nicklas, thank you for help!

                     

                    But anyway, why transactional events doesn't work in case of remote call? At least, non-transactional events works OK... Will play more...

                    • 7. What's wrong with transactional CDI events?
                      nickarls

                      Could you attach a minimal app? If nothing else, the logging is crappy as to why it fails.

                      • 8. Re: What's wrong with transactional CDI events?
                        eugene-71

                        Nicklas Karlsson wrote:

                         

                        Could you attach a minimal app? If nothing else, the logging is crappy as to why it fails.

                         

                        Here builded sources from first post.

                        "ejb" folder contains ejb jar to deploy.

                        "client" folder contains simple remote client, run it with command:

                         

                        java -cp client.jar;TestEjbInterface.jar;<path_to_jbossall-client.jar>\jbossall-client.jar tst.client.Main
                        

                         

                        Here also source of client.java, as not present in first post:

                         

                        package tst.client;
                        
                        import er.tst.T2Remote;
                        import java.util.Properties;
                        import javax.naming.Context;
                        import javax.naming.InitialContext;
                        
                        public class Main
                        {
                            public static void main(String[] args) throws Exception
                            {
                                Properties properties = new Properties();
                                properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
                                properties.put(Context.PROVIDER_URL, "localhost");
                                Context ctx = new InitialContext( properties );
                        
                                Object ref = ctx.lookup( "T2Bean/remote" );
                                T2Remote t = (T2Remote)ref;
                                t.theTest();
                                System.out.println( "theTest() called!" );
                            }
                        } 
                        
                        • 9. Re: What's wrong with transactional CDI events?
                          eugene-71

                          And also debug log for remote call:

                           

                          2011-01-25 09:13:04,359 DEBUG [org.jboss.ejb3.stateless.StatelessContainer] (WorkerThread#0[127.0.0.1:3536]) Received dynamic invocation for method with hash: -4087570856943461660
                          2011-01-25 09:13:04,359 DEBUG [org.jboss.weld.Event] (WorkerThread#0[127.0.0.1:3536]) WELD-000400 Sending event er.tst.TestEvent@151e0c7 directly to observer [method] public er.tst.TestListener.listen(TestEvent)
                          2011-01-25 09:13:04,359 ERROR [org.jboss.weld.Event] (WorkerThread#0[127.0.0.1:3536]) WELD-000401 Failure while notifying an observer of event er.tst.TestEvent@151e0c7
                          2011-01-25 09:13:04,359 DEBUG [org.jboss.weld.Event] (WorkerThread#0[127.0.0.1:3536]) throwing: org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001308 Unable to resolve any beans for Types: [interface org.jboss.weld.context.ejb.EjbRequestContext]; Bindings: [@org.jboss.weld.context.unbound.Unbound()]
                              at org.jboss.weld.manager.BeanManagerImpl.getBean(BeanManagerImpl.java:788) [:6.0.0.Final]
                              at org.jboss.weld.bean.builtin.InstanceImpl.get(InstanceImpl.java:80) [:6.0.0.Final]
                              at org.jboss.weld.event.DeferredEventNotification$RunInRequest.run(DeferredEventNotification.java:103) [:6.0.0.Final]
                              at org.jboss.weld.event.DeferredEventNotification.run(DeferredEventNotification.java:64) [:6.0.0.Final]
                              at org.jboss.weld.event.TransactionSynchronizedRunnable.afterCompletion(TransactionSynchronizedRunnable.java:62) [:6.0.0.Final]
                              at com.arjuna.ats.internal.jta.resources.arjunacore.SynchronizationImple.afterCompletion(SynchronizationImple.java:117) [:6.0.0.Final]
                              at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.afterCompletion(TwoPhaseCoordinator.java:371) [:6.0.0.Final]
                              at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.end(TwoPhaseCoordinator.java:104) [:6.0.0.Final]
                              at com.arjuna.ats.arjuna.AtomicAction.commit(AtomicAction.java:159) [:6.0.0.Final]
                              at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1158) [:6.0.0.Final]
                              at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.commit(BaseTransaction.java:119) [:6.0.0.Final]
                              at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.commit(BaseTransactionManagerDelegate.java:75) [:6.0.0.Final]
                              at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.endTransaction(CMTTxInterceptor.java:82) [:0.0.1]
                              at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:255) [:0.0.1]
                              at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.required(CMTTxInterceptor.java:349) [:0.0.1]
                              at org.jboss.ejb3.tx2.impl.CMTTxInterceptor.invoke(CMTTxInterceptor.java:209) [:0.0.1]
                              at org.jboss.ejb3.tx2.aop.CMTTxInterceptorWrapper.invoke(CMTTxInterceptorWrapper.java:52) [:0.0.1]
                              at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
                              at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76) [:1.0.0.GA]
                              at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
                              at org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42) [:1.0.3]
                              at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
                              at org.jboss.ejb3.security.Ejb3AuthenticationInterceptorv2.invoke(Ejb3AuthenticationInterceptorv2.java:182) [:1.7.17]
                              at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
                              at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:41) [:1.7.17]
                              at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
                              at org.jboss.ejb3.BlockContainerShutdownInterceptor.invoke(BlockContainerShutdownInterceptor.java:67) [:1.7.17]
                              at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
                              at org.jboss.ejb3.core.context.CurrentInvocationContextInterceptor.invoke(CurrentInvocationContextInterceptor.java:47) [:1.7.17]
                              at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
                              at org.jboss.aspects.currentinvocation.CurrentInvocationInterceptor.invoke(CurrentInvocationInterceptor.java:67) [:1.0.1]
                              at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
                              at org.jboss.ejb3.interceptor.EJB3TCCLInterceptor.invoke(EJB3TCCLInterceptor.java:86) [:1.7.17]
                              at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102) [jboss-aop.jar:2.2.1.GA]
                              at org.jboss.ejb3.stateless.StatelessContainer.dynamicInvoke(StatelessContainer.java:392) [:1.7.17]
                              at org.jboss.ejb3.session.InvokableContextClassProxyHack._dynamicInvoke(InvokableContextClassProxyHack.java:53) [:1.7.17]
                              at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:91) [jboss-aop.jar:2.2.1.GA]
                              at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:82) [:1.0.1.GA]
                              at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:898) [:6.0.0.Final]
                              at org.jboss.remoting.transport.socket.ServerThread.completeInvocation(ServerThread.java:791) [:6.0.0.Final]
                              at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:744) [:6.0.0.Final]
                              at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:548) [:6.0.0.Final]
                              at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:234) [:6.0.0.Final]
                          
                          2011-01-25 09:13:04,375 DEBUG [org.jboss.remoting.transport.socket.ServerThread] (WorkerThread#0[127.0.0.1:3536]) WorkerThread#0[127.0.0.1:3536] closed socketWrapper: ServerSocketWrapper[Socket[addr=/127.0.0.1,port=3536,localport=3873].15fe804]
                          
                          • 10. Re: What's wrong with transactional CDI events?
                            nickarls

                            WELD-001308 Unable to resolve any beans for Types: [interface org.jboss.weld.context.ejb.EjbRequestContext]; Bindings: [@org.jboss.weld.context.unbound.Unbound()]

                            • 11. What's wrong with transactional CDI events?
                              eugene-71

                              Nicklas Karlsson wrote:

                               

                              WELD-001308 Unable to resolve any beans for Types: [interface org.jboss.weld.context.ejb.EjbRequestContext]; Bindings: [@org.jboss.weld.context.unbound.Unbound()]

                              Yes, but what to do?

                              • 12. What's wrong with transactional CDI events?
                                nickarls

                                Hmm, I haven't really used remote EJBs. So you get a reference to the true EJB proxy (not the CDI one but CDI has done injection on it) through JNDI. Then you invoke the method and apparently it goes down the correct route (I see DeferredEventNotificationoned) but then the DeferredEventNotification.RunInRequest does a

                                 

                                RequestContext requestContext = Container.instance().deploymentManager().instance().select(EjbRequestContext.class, UnboundLiteral.INSTANCE).get();

                                 

                                expecting to resolve the EjbRequestContext class and it's a no-go. Hmmm(tm). In which placed do you have beans.xml?

                                • 13. What's wrong with transactional CDI events?
                                  eugene-71

                                  Nicklas Karlsson wrote:

                                   

                                  In which placed do you have beans.xml?

                                  In ejb jar... TestEjb.jar/META-INF/beans.xml

                                   

                                  You may look at attachment in earlier post.

                                  • 14. What's wrong with transactional CDI events?
                                    nickarls

                                    You might want to check in http://seamframework.org/Community/WeldUsers if it's supposed to work...