1 2 3 4 Previous Next 52 Replies Latest reply on Apr 7, 2008 6:29 AM by timfox Go to original post
      • 15. Re: Bug in transactional delivery in an MDB
        timfox

        This is now fixed in TRUNK.

        I still need to backport the fix to 1.0

        • 16. Re: Bug in transactional delivery in an MDB
          timfox

           

          "adrian@jboss.org" wrote:


          There is actually nothing in the spec about this behaviour.
          The XA stuff is massively underspecified in the JMS spec.
          And of course it is optional whether a JMS impl supports XA.

          The JBossMQ behaviour is to assume that an XASession behaves like
          AUTO_ACKNOWLEDGE when the XASession is not enlisted in a JTA transaction.
          (Some JMS implements throw an exception in this case).

          There is one exception to this. When the XASession is being used as part of
          a ServerSessionPool, the semantics need to be receive then enlist.
          So for this, the XASession behaves like there is a transaction, it will be told
          later what XID to use for the 2PC protocol.


          What I don't quite understand is how the session knows it has been created via a session pool rather than any other way so it can have different behaviour.

          I couldn't work out immediately from the JBoss MQ code how this info is passed to the session.

          Any ideas?

          • 17. Re: Bug in transactional delivery in an MDB
            clebert.suconic

            The only issue I'm having now, is when using a nonTransaction session, like this case, when inside an transactioned EJB:

             ConnectionFactory cf = jndi.lookup("java:/JmsXA");
             Connection conn = cf.createConnection();
             session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
             MessageProducer producer = session.createProducer(replyTo);
             producer.send(session.createTextMessage("NonTransactioned message"));
             session.close();
            


            This following code, only works if we commit the UserTransaction, or if a ContainerManagedTransaction completes its execution.

            From what I have seen on TCK tests, this is supposed to really behave as a nonTransacted session and this shouldn't require the userTransaction.commit to send that message.

            Any thoughts?

            • 18. Re: Bug in transactional delivery in an MDB
              clebert.suconic

              I have found some inconsistences between JCA and Messaging.

              It looks like JBossMQ would return a XAConnection only under certain circustances, and JBossMQFActory would take the decision wether the Connection should be XA or not.

              And it happens that our Connection is aways a XA Connection

               public class JBossConnection implements
               Connection, QueueConnection, TopicConnection,
               XAConnection, XAQueueConnection, XATopicConnection, Serializable
              



              So, looking at JCA Code, you have several places like this:



              
              package org.jboss.resource.adapter.jms;
              
              
              .....
              
              public class JmsManagedConnection
               implements ManagedConnection, ExceptionListener
              {
              
              .....
              
               private void setup() throws ResourceException
               {
              
               ................
              
               if (con instanceof XATopicConnection)
               {
               xaTopicSession = ((XATopicConnection)con).createXATopicSession();
               topicSession = xaTopicSession.getTopicSession();
               xaTransacted = true;
               }
               else if (con instanceof TopicConnection)
               {
               topicSession =
               ((TopicConnection)con).createTopicSession(transacted, ack);
               if (trace)
               log.trace("Using a non-XA TopicConnection. " +
               "It will not be able to participate in a Global UOW");
               }
               else
               throw new JBossResourceException("Connection was not recognizable: " + con);
              
               if (trace)
               log.trace("xaTopicSession=" + xaTopicSession + ", topicSession=" + topicSession);
               }
              
               ................
               }
              
              ......
              }
              



              If what I'm saying is correct (That the MQ.ConnectionFactory would take the decision on return a XAConnection or not), we have two options:

              I - Refactor the JCA layer to be more compatible with our Messaging approach
              II - Refactor Messaging to only return XAConnections when it's necessary.


              Just to conclude, This case, where our connection is aways a XAConnection, it is making JCA to ignore the parameter transactioned when you do connection.createSession(false, ...)

              Any thoughts?





              • 19. Re: Bug in transactional delivery in an MDB
                weston.price

                This would be an unusual case as most JMS providers provide both a non XA and an optional XA CF to create the underlying connection. What I am reading is that JBM does not provide the former as a standalone CF option.

                The problem is that on the JCA side of things there is no way to determine from the 'transacted' parameter whether or not XA or non XA is to be used being that with XA this flag is simply ignored. In other words, the value of that flag is irrelevant in detrmining what type of connection to use (XA or non XA) being that there is not enough contextual information to make that determination. The only way to really do this would be to add a 'useXA' or 'isXA' type flag to the adapter that when present, would completely override the instanceof check to determine if it's XA or not. I am reluctant to do this as this as this would be the only case with a JMS provider where it it is necessary.


                JBM would be the only JMS provider I have seen to date where you could not deploy a non XA JMS resource. WebSphereMQ, TIBCO, ActiveMQ, JBossMQ etc provide XA as an option as this is the only behavior mandated by the spec where the XA is optional.




                • 20. Re: Bug in transactional delivery in an MDB
                  clebert.suconic

                  I guess we will have to make a clear distinction between XA and non XA connections.

                  http://jira.jboss.org/jira/browse/JBMESSAGING-945


                  Tim? What you think?

                  • 21. Re: Bug in transactional delivery in an MDB
                    timfox

                     

                    "weston.price@jboss.com" wrote:
                    This would be an unusual case as most JMS providers provide both a non XA and an optional XA CF to create the underlying connection.

                    JBM would be the only JMS provider I have seen to date where you could not deploy a non XA JMS resource. WebSphereMQ, TIBCO, ActiveMQ, JBossMQ etc provide XA as an option as this is the only behavior mandated by the spec where the XA is optional.



                    Well, yes I agree this may be unusual, although I don't believe it it illegal.

                    It seems to me the JCA is making an incorrect assumption that a particular connection instance can't be both a Connection and an XAConnection. It just so happens up to now JBM is the only provider that implements it this way.

                    Having said all that, to get this fixed quickly, it should be fairly trivial for us to make the change in JBM to separate out the Connection and XAConnection classes. So I suggest we do that.

                    • 22. Re: Bug in transactional delivery in an MDB
                      clebert.suconic

                      I have an integration testsuite at https://svn.jboss.org/repos/messaging/projects/jms-integration/

                      I belive we should also change one of the smoke tests to use a non transacted session.

                      • 23. Re: Bug in transactional delivery in an MDB
                        clebert.suconic

                        Just to add some information on this:

                        At JmsActivation the transactional attribute is taken in consideration. So.. even CF is a XAConnectionFActory it wouldn't use the XA method if the transactional parameter is false on a createSession request.

                        Relevant code:

                        package org.jboss.resource.adapter.jms.inflow;
                        
                        public class JmsActivation implements ExceptionListener
                        {
                        
                        ....
                        
                         protected TopicConnection setupTopicConnection(Context ctx, String
                        user, String pass, String clientID) throws Exception
                         {
                         String topicFactoryRef = adapter.getTopicFactoryRef();
                         log.debug("Attempting to lookup topic connection factory " +
                        topicFactoryRef);
                         TopicConnectionFactory tcf = (TopicConnectionFactory)
                        Util.lookup(ctx, topicFactoryRef, TopicConnectionFactory.class);
                         log.debug("Got topic connection factory " + tcf + " from " +
                        topicFactoryRef);
                         log.debug("Attempting to create topic connection with user " +
                        user);
                         TopicConnection result;
                         if (tcf instanceof XATopicConnectionFactory &&
                        isDeliveryTransacted)
                         {
                         XATopicConnectionFactory xatcf = (XATopicConnectionFactory)
                        tcf;
                         if (user != null)
                         result = xatcf.createXATopicConnection(user, pass);
                         else
                         result = xatcf.createXATopicConnection();
                         }
                         else
                         {
                         if (user != null)
                         result = tcf.createTopicConnection(user, pass);
                         else
                         result = tcf.createTopicConnection();
                         }
                         if (clientID != null)
                         result.setClientID(clientID);
                         result.setExceptionListener(this);
                         log.debug("Using topic connection " + result);
                         return result;
                         }
                        
                        ....
                        }
                        

                        This way a non transacted Session would be aways a plain Connection...
                        but not for us!

                        • 24. Re: Bug in transactional delivery in an MDB
                          timfox

                          It's my understanding that the JMSActivation will be used for an MDB but if you create a connection directly (from inside your Ejb for instance) using the managed connection factory then (if it can't find an appropriate cached one) then a new JMSManagedConnection will be created and JMSManagedConnection::setup() wil be called.

                          AFAICT This will always end up creating an XAConnection (even for JBoss MQ) if the default JMSProviderAdapter is used, since the default JMSProviderAdapter shipped with AS4.x always looks up using /XAConnectionFactory.

                          So I don't see how separating out Connection and XAConnection is going to help.

                          • 25. Re: Bug in transactional delivery in an MDB
                            clebert.suconic

                            Maybe there's still a bug on JCA at the end.

                            We are going to separate this... if on the end we still have problems we will kick Weston :-)

                            • 26. Re: Bug in transactional delivery in an MDB
                              weston.price

                               


                              Well, yes I agree this may be unusual, although I don't believe it it illegal.


                              No, not illegal but it certainly makes deploying non XA JMS based resources with JBM all but impossible while using the JMS/JCA adapter. While this is not necessarily a bad thing, it simply says that when using JCA/JMS in conjunction with JBM you currently have no choice but to use XA which in most scenarios is exactly what you want.


                              It seems to me the JCA is making an incorrect assumption that a particular connection instance can't be both a Connection and an XAConnection. It just so happens up to now JBM is the only provider that implements it this way.


                              The JMS/JCA adapter does not make any assumptions beyond that which is specified in the requisite configuration files (ie *-ds.xml for outbound connectivity and the activation-configuration for inbound).

                              The JCA/JMS adapter is designed for generic JMS integration with any JMS provider, not just those implementing the optional XA API.
                              What is bound into JNDI and relayed to the adapter via the JMSProviderAdapter is what determines it's use in the context of a global transaction.

                              If an XAConnectionFactory (or it's XA specific counterparts per domain) is bound into JNDI and registered with the adapter via the JMSProviderAdapter configuration property, the adapter uses this. If not, the traditional JMS API is used.

                              This is *by design*. Being that XA is optional for an JMS provider this is used to support providers that do not implement XA but still may want to participate in a global transaction via the LRCG (Last resource commit gambit) much in the same manner as the local-tx-datasource. Similarly, it is used to support clients that do not want to use XA at all and be transaction ignorant (no-tx-connection-factory) and perhaps utilize the local JMS transaction API to control the transaction themselves (Session.commit(), Session.rollback()) while still getting the benefit of connection pooling.

                              In other words, if you want XA you deploy the correct JMS adminstrative objects to support this. If not, or you can't because your JMS provider doesn't support it, you don't. To reflect this you configure your *-ds.xml file (and JMSProviderAdapter) appropriately.

                              Having said all of this, I am not sure that any of this is the cause of the failures in the testsuite/TCK. Without specific stack traces/errors I can't determine what the issue is or if it pertains to JCA/JMS at all. The test offered an example is a perfectly supported use case under JBossMQ, but that isn't saying all that much. Without more information, I simply can't tell. I am more than happy to look at the issues if you want just point me to a specific trace/error that I can review.












                              • 27. Re: Bug in transactional delivery in an MDB
                                weston.price

                                Also, it should be noted that while the JMS API does not require XA support, the J2EE specification requires that a JMS provider must be supported as a transactional resource manager (Section 4.2.8 in both in 1.4 and EE 5). The JMS/JCA adapter is the fullfilment of this requirement.





                                • 28. Re: Bug in transactional delivery in an MDB
                                  timfox

                                   

                                  "weston.price@jboss.com" wrote:

                                  No, not illegal but it certainly makes deploying non XA JMS based resources with JBM all but impossible while using the JMS/JCA adapter. While this is not necessarily a bad thing, it simply says that when using JCA/JMS in conjunction with JBM you currently have no choice but to use XA which in most scenarios is exactly what you want.


                                  But it is not what we want all cases


                                  The JCA/JMS adapter is designed for generic JMS integration with any JMS provider, not just those implementing the optional XA API.


                                  If it's designed for generic JMS integration with ANY JMS provider then it fails on its own requirement with JBM



                                  This is *by design*.



                                  Sounds like the design is broken. You are forcing us to always be always used as XA, because you use instanceof to tell the XAConnectionFactory and ConnectionFactory apart.

                                  I.e. the JCA implementation currently implicitly assumes that the a particular JMS provider won't use the same class to implement XA and non XA interfaces.

                                  As you yourself mentioned earlier in this thread, another solution which should work with all (read JBM) JMS providers is to add extra field "isXA" in the JMSProviderAdapter config.

                                  Or perhaps something like this - with explicit extra fields:

                                   <mbean code="org.jboss.jms.jndi.JMSProviderLoader"
                                   name="jboss.messaging:service=JMSProviderLoader,name=JMSProvider">
                                   <attribute name="ProviderName">DefaultJMSProvider</attribute>
                                   <attribute name="ProviderAdapterClass">org.jboss.jms.jndi.JNDIProviderAdapter</attribute>
                                   <attribute name="NonXAFactoryRef">java:/NonXAConnectionFactory</attribute>
                                   <attribute name="NonXAQueueFactoryRef">java:/NonXAConnectionFactory</attribute>
                                   <attribute name="NonXATopicFactoryRef">java:/NonXAConnectionFactory</attribute>
                                   <attribute name="XAFactoryRef">java:/XAConnectionFactory</attribute>
                                   <attribute name="XAQueueFactoryRef">java:/XAConnectionFactory</attribute>
                                   <attribute name="XATopicFactoryRef">java:/XAConnectionFactory</attribute>
                                   </mbean>
                                  













                                  • 29. Re: Bug in transactional delivery in an MDB
                                    weston.price

                                     


                                    But it is not what we want all cases


                                    Then you wouldn't use JCA. Keep in mind there is nothing to prevent you from using JMS without the JCA integration if you don't want pooling and automatic transaction enlistment. You can always use the non JCA CF from JNDI. The JCA resource adapter is designed to provide transactional support to Servlet and EJB appliation components in transparent manner in the same vein as JDBC resources (also JCA).


                                    Sounds like the design is broken. You are forcing us to always be always used as XA, because you use instanceof to tell the XAConnectionFactory and ConnectionFactory apart.


                                    The JMS/JCA adapter is an XA resource adapter, it's purpose is to support a JMS provider as a transactional resource. In the case that the JMS provider is not XA capable (not desired) then we use the local JMS API to achieve the same results via an XA compliant wrapper and the LRCG. The local API is a fallback in the case that that the provider does not support XA.

                                    I would be surpised is any of this is effecting the testsuite/TCK. But again, without a stack trace or any other information I can't say for sure.