1 2 Previous Next 22 Replies Latest reply on Jan 20, 2007 1:58 PM by weston.price

    Problems JCA JMS inflow issue and tx NotSupported

    timfox

      Weston - sorry to bug you again.

      I'm using the JCA inflow invoker-proxy-binding in JBoss-4.0.5.GA for MDBs, and I'm using JBoss Messaging as the JMS provider.

      I have the following trivial MDB:

      public class MDBExample implements MessageDrivenBean, MessageListener
      {
       public void onMessage(Message m)
       {
       System.out.println("got message " + m);
       }
      
       public void ejbCreate()
       {
       }
      
       public void ejbRemove()
       {
       }
      }
      
      <ejb-jar>
       <enterprise-beans>
       <message-driven>
       <ejb-name>MDBExample</ejb-name>
       <ejb-class>org.jboss.example.jms.mdb.MDBExample</ejb-class>
       <transaction-type>Container</transaction-type>
       <message-driven-destination>
       <destination-type>javax.jms.Queue</destination-type>
       </message-driven-destination>
       </message-driven>
       </enterprise-beans>
      
       <assembly-descriptor>
       <container-transaction>
       <method>
       <ejb-name>MDBExample</ejb-name>
       <method-name>*</method-name>
       </method>
       <trans-attribute>Required</trans-attribute>
       </container-transaction>
       </assembly-descriptor>
      </ejb-jar>
      


      I sent a message, and it all works fine, the message gets consumed and acked.

      I then change the trans-attribute to "NotSupported", so the onMessage should not be run in a tx context, and send a message again, and I get:

      10:59:37,437 ERROR [JmsServerSession] Failed to commit session transaction
      javax.jms.TransactionInProgressException: Cannot call commit on an XA session
       at org.jboss.jms.client.container.TransactionAspect.handleCommit(TransactionAspect.java:97)
       at org.jboss.aop.advice.org.jboss.jms.client.container.TransactionAspect14.invoke(TransactionAspect14.java)
       at org.jboss.jms.client.delegate.ClientSessionDelegate$commit_8461082169793485964.invokeNext(ClientSessionDelegate$commit_8461082169793485964.
      java)
       at org.jboss.jms.client.container.ClosedInterceptor.invoke(ClosedInterceptor.java:182)
       at org.jboss.aop.advice.PerInstanceInterceptor.invoke(PerInstanceInterceptor.java:117)
       at org.jboss.jms.client.delegate.ClientSessionDelegate$commit_8461082169793485964.invokeNext(ClientSessionDelegate$commit_8461082169793485964.
      java)
       at org.jboss.jms.client.container.ExceptionInterceptor.invoke(ExceptionInterceptor.java:69)
       at org.jboss.jms.client.delegate.ClientSessionDelegate$commit_8461082169793485964.invokeNext(ClientSessionDelegate$commit_8461082169793485964.
      java)
       at org.jboss.jms.client.container.ClientLogInterceptor.invoke(ClientLogInterceptor.java:107)
       at org.jboss.jms.client.delegate.ClientSessionDelegate$commit_8461082169793485964.invokeNext(ClientSessionDelegate$commit_8461082169793485964.
      java)
       at org.jboss.jms.client.delegate.ClientSessionDelegate.commit(ClientSessionDelegate.java)
       at org.jboss.jms.client.JBossSession.commit(JBossSession.java:165)
       at org.jboss.resource.adapter.jms.inflow.JmsServerSession$LocalDemarcationStrategy.end(JmsServerSession.java:341)
       at org.jboss.resource.adapter.jms.inflow.JmsServerSession.run(JmsServerSession.java:260)
       at org.jboss.resource.work.WorkWrapper.execute(WorkWrapper.java:204)
       at org.jboss.util.threadpool.BasicTaskWrapper.run(BasicTaskWrapper.java:275)
       at EDU.oswego.cs.dl.util.concurrent.PooledExecutor$Worker.run(PooledExecutor.java:743)
       at java.lang.Thread.run(Thread.java:534)
      


      I.e. it fails.

      A couple of things I don't understand:

      Why is there a transaction in the first place? The onMessage is supposed to run without a transaction and should be using the ack mode specified on the ejb (either dups_ok or auto_ack)

      Why is JCA attempting to call commit() on it? The session that the JCA layer creates is an XASession and calling commit() on an XASession is illegal.
      (see http://java.sun.com/j2ee/1.4/docs/api/index.html)

      For a "NotSupported" method, I would expect the session used to do the message consumption to be a standard non XA session obtained from a standard non XA JMS connection, and I wouldn't expect commit to be called on it.



        • 1. Re: Problems JCA JMS inflow issue and tx NotSupported
          timfox

           

          "timfox" wrote:

          For a "NotSupported" method, I would expect the session used to do the message consumption to be a standard non XA session obtained from a standard non XA JMS connection, and I wouldn't expect commit to be called on it.



          I suppose for a CMT method in a "Non specified" tx context I guess it is legal to run it in a local tx (although I'm not sure why that was chosen rather than just having no tx).

          Although I get the same exception when running with BMT in which case the transaction context is not considered "unspecified" so running it in a local tx would seem illegal to me.

          • 2. Re: Problems JCA JMS inflow issue and tx NotSupported
            weston.price

             


            I suppose for a CMT method in a "Non specified" tx context I guess it is legal to run it in a local tx (although I'm not sure why that was chosen rather than just having no tx).


            To support redelivery of a message for an MDB that throws a RuntimeException in a 'non specified transaction context'.

            Being that JCA has to be JMS provider agnostic if a listener throws a runtime exception and the transactional attribute is NotSupported (BMT or CMT) and the client wants the message to be redelivered, the only way to achieve this in a neutral manner is to use transactions. Note, neither the JMS or the EJB spec prohibit this being that the transactional handling of a receipt of a message in an unspecified context is left up to the vendor.

            Unfortunately, the 4.0.5 code base, as opposed to the refactoring in HEAD, uses a 1PC optimization on an XAResource which was not a good design to begin with. The latest code uses local JMS transactions both for performance reasons, as well as for clarity in the BMT/CMT NotSupported scenario.

            • 3. Re: Problems JCA JMS inflow issue and tx NotSupported
              timfox

              There is still the problem that the JCA layer is calling commit() on an XASession which is an illegal JMS operation.

              How can we fix this?

              • 4. Re: Problems JCA JMS inflow issue and tx NotSupported
                timfox

                Looking through the 4.0.5 JCA code I think I can see what is happening:

                In the CMT case, the onMessage is marked as NotSupported so the JMSServerSession chooses a LocalDemarcationStrategy even though the connection is an XAConnection.

                Then bang,

                javax.jms.TransactionInProgressException: Cannot call commit on an XA session
                 at org.jboss.jms.client.container.TransactionAspect.handleCommit(TransactionAspect.java:97)
                 at org.jboss.aop.advice.org.jboss.jms.client.container.TransactionAspect14.invoke(TransactionAspect14.java)
                 at org.jboss.jms.client.delegate.ClientSessionDelegate$commit_8461082169793485964.invokeNext(ClientSessionDelegate$commit_8461082169793485964.java)
                 at org.jboss.jms.client.container.ClosedInterceptor.invoke(ClosedInterceptor.java:182)
                 at org.jboss.aop.advice.PerInstanceInterceptor.invoke(PerInstanceInterceptor.java:117)
                 at org.jboss.jms.client.delegate.ClientSessionDelegate$commit_8461082169793485964.invokeNext(ClientSessionDelegate$commit_8461082169793485964.java)
                 at org.jboss.jms.client.container.ExceptionInterceptor.invoke(ExceptionInterceptor.java:69)
                 at org.jboss.jms.client.delegate.ClientSessionDelegate$commit_8461082169793485964.invokeNext(ClientSessionDelegate$commit_8461082169793485964.java)
                 at org.jboss.jms.client.container.ClientLogInterceptor.invoke(ClientLogInterceptor.java:107)
                 at org.jboss.jms.client.delegate.ClientSessionDelegate$commit_8461082169793485964.invokeNext(ClientSessionDelegate$commit_8461082169793485964.java)
                 at org.jboss.jms.client.delegate.ClientSessionDelegate.commit(ClientSessionDelegate.java)
                 at org.jboss.jms.client.JBossSession.commit(JBossSession.java:165)
                 at org.jboss.resource.adapter.jms.inflow.JmsServerSession$LocalDemarcationStrategy.end(JmsServerSession.java:341)
                 at org.jboss.resource.adapter.jms.inflow.JmsServerSession.run(JmsServerSession.java:260)
                 at org.jboss.resource.work.WorkWrapper.execute(WorkWrapper.java:204)
                 at org.jboss.util.threadpool.BasicTaskWrapper.run(BasicTaskWrapper.java:275)
                 at EDU.oswego.cs.dl.util.concurrent.PooledExecutor$Worker.run(PooledExecutor.java:743)
                


                as the ServerSession tries to
                call commit() which clearly will fail.

                Interestingly the same problem occurs with BMT as well even though no transaction should have been started at all. BMT doesn't count as an "unspecified tx context" so the reasoning for starting a tx there shouldn't apply as it does for CMT.

                • 5. Re: Problems JCA JMS inflow issue and tx NotSupported
                  timfox

                   

                  "timfox" wrote:

                  Interestingly the same problem occurs with BMT as well even though no transaction should have been started at all. BMT doesn't count as an "unspecified tx context" so the reasoning for starting a tx there shouldn't apply as it does for CMT.


                  Hmmm, it seems that if I omit the acknowledge-mode from the MDB deployment descriptor when using BMT, then it defaults to transacted.

                  This seems to be in contravention to the EJB spec:

                  15.4.8

                  If the acknowledge-mode deployment
                  descriptor element is not specified, JMS AUTO_ACKNOWLEDGE semantics are assumed.


                  This would explain the above behaviour: The JCA adaptor is creating an xasession on the xaconnection even though it's BMT (and should be auto_ack since I haven't specified acknowledge-mode), then trying to call commit on it at the end.

                  Instead, it should be creating a non transacted session, on a non xa connection and not calling commit at the end since it's non transacted.




                  • 6. Re: Problems JCA JMS inflow issue and tx NotSupported
                    weston.price

                    As I have said, I believe more than a few times now, the 4.0.5 code was backported randomly and really should never have been done (believe me, I yelled and screamed about this for quite awhile but to no avail). The code in HEAD should really be ported or installed as a patch.

                    Please note, just because JCA starts/terminates a transaction does not mean that the onMessage method executes in this context. If NotSupported or BMT is used, the EJB container will suspend the transaction appropriately.


                    Hmmm, it seems that if I omit the acknowledge-mode from the MDB deployment descriptor when using BMT, then it defaults to transacted.


                    No, it's not. acknowledgement modes are used only in the case of a *non* tranascted session. The spec is merely saying that if the client is using a transacted session, then the ack mode is AUTO_ACKNOWLEDGE which is just simply a convention in this case as has no overall effect.


                    Instead, it should be creating a non transacted session, on a non xa connection and not calling commit at the end since it's non transacted.


                    No, it doesn't.

                    • 7. Re: Problems JCA JMS inflow issue and tx NotSupported
                      timfox

                       

                      "weston.price@jboss.com" wrote:

                      The spec is merely saying that if the client is using a transacted session, then the ack mode is AUTO_ACKNOWLEDGE which is just simply a convention in this case as has no overall effect.


                      I realise that if the session is transacted, then the ack mode is ignored, but that's not what the spec is saying. Here it is in full:

                      EJB 2 spec 15.4.8:

                      If bean managed transaction demarcation is used, the message receipt cannot be
                      part of the bean-managed transaction, and, in this case, the receipt is acknowledged by the container. If
                      bean managed transaction demarcation is used, the Bean Provider can indicate in the
                      acknowedge-mode deployment descriptor element whether JMS AUTO_ACKNOWLEDGE semantics
                      or DUPS_OK_ACKNOWLEDGE semantics should apply. If the acknowledge-mode deployment
                      descriptor element is not specified, JMS AUTO_ACKNOWLEDGE semantics are assumed.


                      What the spec is saying, is that if you are using BMT then the message receipt will be acked using a local non transacted session, that is either AUTO_ACK or DUPS_OK, AND if the user omits to specify which ack mode in the deployment descriptor then it will use AUTO_ACK. This ack mode is *not* ignored, it used for the message receipt.

                      What I observe in practice, using JBM and the 4.0.5.GA JCA, is that if I specify the ackmode, then it all works fine (my trivial example), the message is received and acknowledged.

                      If I fail to specify the ack mode, I can see the JCA layer creating a *transacted* XA session, and trying to call commit on it.

                      Bottom line is JBM works with the JMSContainerInvoker but not with JCA inflow in 4.0.5, even for this most trivial example.

                      I'm not trying to attribute blame, just trying to work out what is going on, and find a solution. :)

                      This is either a problem in JBM or a problem with JCA. Right now I believe it is a bug in JCA because the JCA layer is trying to call commit on an XASession which seems clearly wrong to me. Although I am willing to accept there is a bug in JBM if you can come up with another explanation.

                      If you are saying that the 4.0.5.GA code is a bodged backport and basically doesn't work, and there's no chance of getting it fixed, then we can tell our customers not to use that and stick with the JMSContainerInvoker until JB5.

                      (What about AS4.2 - I would have thought we would want the good HEAD version in that?)

                      This isn't ideal but if that's the situation, then we have to live with that.

                      For JBM1.2, we need to make sure that all these cases work, so I am going to improve the MDB integration tests and make sure they run with both the JMSContainerInvoker and JCA1.5 inflow.

                      Right now the MDB test coverage is scrappy (no blame) to say the least which is why issues like this and others are slipping through the net.




                      • 8. Re: Problems JCA JMS inflow issue and tx NotSupported
                        weston.price

                        The *easiest* thing to do would be to patch 4.0.5 and then make this patch available in the next cummulative patch release. The changes that made it in to 4.0.5 should simply be replaced with the new stuff. This will be the case with 4.2. Again, this is why I never wanted this backport to happen.


                        I'm not trying to attribute blame, just trying to work out what is going on, and find a solution. :)


                        Your altruism is quite refreshing.


                        If you are saying that the 4.0.5.GA code is a bodged backport and basically doesn't work, and there's no chance of getting it fixed, then we can tell our customers not to use that and stick with the JMSContainerInvoker until JB5.


                        That is not what I am saying. I am more that willing to address any issues you think might be occuring with JCA and JBM. Again, a patch release in our cummulative QA patch cycle is most likely the best approach.


                        (What about AS4.2 - I would have thought we would want the good HEAD version in that?)


                        Yes, the code in HEAD will be in 4.2.


                        For JBM1.2, we need to make sure that all these cases work, so I am going to improve the MDB integration tests and make sure they run with both the JMSContainerInvoker and JCA1.5 inflow.


                        Yes, this is simply a matter of running the testsuite against HEAD really where JBM is the default. Unfortunately, I haven't paid much attention to this as most of us are working on getting the TCK issues resolved and finalized.


                        Right now the MDB test coverage is scrappy (no blame) to say the least which is why issues like this and others are slipping through the net.


                        Not really. There is a decent framework for testing both the JCA adapter and the container invoker. Again, I think this is simply a matter of dealing with JBM which up until recently I was aware had any issues. Since this is the first time I am hearing about this and 4.0.5 has been in the wild for a bit (at least enough time to accumulate a patch release), I am assuming that we are simply running into some scenarios with JCA/JBM that have not been accounted for at this point.









                        • 9. Re: Problems JCA JMS inflow issue and tx NotSupported
                          timfox

                           

                          "weston.price@jboss.com" wrote:

                          Yes, this is simply a matter of running the testsuite against HEAD really where JBM is the default. Unfortunately, I haven't paid much attention to this as most of us are working on getting the TCK issues resolved and finalized.


                          Richard Achmatowicz is currently working on this. The end result is that both JBossMQ and JBM will run using the same set of integration tests.


                          Not really. There is a decent framework for testing both the JCA adapter and the container invoker. Again, I think this is simply a matter of dealing with JBM which up until recently I was aware had any issues. Since this is the first time I am hearing about this and 4.0.5 has been in the wild for a bit (at least enough time to accumulate a patch release), I am assuming that we are simply running into some scenarios with JCA/JBM that have not been accounted for at this point.


                          I had a good look in the test suite for MDB integration tests yesterday.

                          I started a thread on the dev list yesterday about this - have you seen it?

                          Scott pointed me in the direction of where the tests are. I had a look and it seemed to me the coverage was poor.

                          If there is a decent framework I guess I must have been looking in the wrong place. Can you point me in the right direction?









                          • 10. Re: Problems JCA JMS inflow issue and tx NotSupported
                            bill.burke

                            tell our customers not to use JCA is not an option for EJB3 users as we are only Inflow based.

                            • 11. Re: Problems JCA JMS inflow issue and tx NotSupported
                              weston.price

                              Now, that is indeed an issue. There are some in org.jboss.test.messagedriven.test and some in the jca pacakges. I was planning on unifying these because I wrote a mock framework to make testing the adapter easier. I can bump this up the priority list and get it checked in.

                              If you guys have anything similar in JBM let me know so we aren't duplicating efforts.

                              • 12. Re: Problems JCA JMS inflow issue and tx NotSupported
                                timfox

                                The tests really shouldn't care if the underlying implementation is using JCA or ASF.

                                We just need some tests that test every combination (there aren't that many), i.e.:

                                CMT:

                                tx Required:

                                test message receipt.
                                test message is not acked until onMessage returned
                                test throwing RuntimeException
                                test throwing Checked exception
                                test setRollbackOnly
                                etc

                                tx Not Supported

                                first define what the behaviour should be then do the same tests as tx required and check results conform to defined behaviour

                                BMT:

                                Check that message is acked according to ack mode specified in config, i.e. AUTO_ACK, DUPS_OK.

                                Check that defaults to AUTO_ACK if not specified.

                                use UT to being and commit /rollback tx. do some other transactional operation in the UT (e.g. send to another MDB)

                                Then repeat all the above using MDB on queue, topic with durable and non durable subscripton, selector etc.

                                So this isn't about testing the adapter, AFAIK the adapter tests look pretty thorough.

                                This is about testing MDB functionality, and should be agnostic of the implementation.

                                Then we just run the exact same of tests swapping out the invoker-proxy-binding for either JMSContainerInvoker or JCA inflow, and repeat again for JbossMQ and JBM.

                                Should pass all tests in all 4 configurations.

                                • 13. Re: Problems JCA JMS inflow issue and tx NotSupported
                                  weston.price

                                  This is effectively what the framework does, both for ASF and for JCA. I will verify this, but I am sure a majority of those cases are covered.

                                  • 14. Re: Problems JCA JMS inflow issue and tx NotSupported
                                    timfox

                                    Weston-

                                    Have you worked out why the JCA layer is calling commit on a transacted session?

                                    I am assuming this is a JCA bug, is there a JIRA task for it?

                                    1 2 Previous Next