ActiveMQ
  1. ActiveMQ
  2. AMQ-2656

ActiveMQInitialConnectionFactory cannot return an XAConnectionFactory

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 5.3.0
    • Fix Version/s: 5.4.0, 5.7.0
    • Component/s: JMS client
    • Labels:
      None

      Description

      ActiveMQInitialContextFactory cannot resolve the name "XAConnectionFactory" a la:

      INFO: JNDI API lookup failed: javax.naming.NameNotFoundException: XAConnectionFactory

      This prevents using the builtin JNDI service in an XA transaction context. I've created a simple patch to workaround this and discussed it on the mailing list: http://old.nabble.com/ActiveMQ%27s-JNDI-does-not-resolve-XAConnectionFactory-td27936255.html

        Issue Links

          Activity

          Hide
          Gary Tully added a comment -

          added support for a boolean xa property in the environment which will cause an xa connection factory to be created. r924972

          xa=true

          or on a lookup name basis

          connection.<name>.xa=true

          will result in an XAConnectionFactory being created.

          Show
          Gary Tully added a comment - added support for a boolean xa property in the environment which will cause an xa connection factory to be created. r924972 xa= true or on a lookup name basis connection.<name>.xa= true will result in an XAConnectionFactory being created.
          Hide
          Edan idzerda added a comment -

          This is my patched version that allows me to jndiContext.lookup("XAConnectionFactory") and get a working XAConnectionFactory.

          Show
          Edan idzerda added a comment - This is my patched version that allows me to jndiContext.lookup("XAConnectionFactory") and get a working XAConnectionFactory.
          Hide
          Edan idzerda added a comment - - edited

          Gary, will your patch (I can't see it yet) allow me to JNDI lookup "XAConnectionFactory" ? That may be all I have available in webMethods "JNDI Provider Alias" settings. I guess I can try to lookup connection.MyConnection or something along those lines.

          Show
          Edan idzerda added a comment - - edited Gary, will your patch (I can't see it yet) allow me to JNDI lookup "XAConnectionFactory" ? That may be all I have available in webMethods "JNDI Provider Alias" settings. I guess I can try to lookup connection.MyConnection or something along those lines.
          Hide
          Gary Tully added a comment -

          check out the subversion commits tag to see the changes.

          It may not be enough for you if you cannot augment the environment to add the xa=true property.
          there is also a property for the connectionFactoryNames where you can provide the list of names you will expect. This overrides the DEFAULT_CONNECTION_FACTORY_NAMES

          Show
          Gary Tully added a comment - check out the subversion commits tag to see the changes. It may not be enough for you if you cannot augment the environment to add the xa=true property. there is also a property for the connectionFactoryNames where you can provide the list of names you will expect. This overrides the DEFAULT_CONNECTION_FACTORY_NAMES
          Hide
          Edan idzerda added a comment -

          At least from work, it took a while for the source code to show up in Crucible. I saw it before I left work, but I wasn't able to get it to work. I'll try again tomorrow, but I get ClassCastException trying to cast ActiveMQConnectionFactory to ActiveMQXAConnectionFactory. Maybe that should work since it's a subclass, but that error makes me doubtful So far I've only been successful with my patch which returns an ActiveMQXAConnectionFactory specifically.

          From within webMethods, I can set "other properties" which seem to be "jndi.properties." I tried adding "MyConnection" to my custom list of connectionFactoryNames, but I was unsuccessful performing a context.lookup() on "MyConnection.xa=true" or "connection.MyConnection.xa=true" ...

          If I can get your patch working, I still want to modify the DEFAULT_CONNECTION_FACTORY_NAMES to include "XAConnectionFactory" to make it available as easily as the other standard JMS types. Thanks for your help on this

          Show
          Edan idzerda added a comment - At least from work, it took a while for the source code to show up in Crucible. I saw it before I left work, but I wasn't able to get it to work. I'll try again tomorrow, but I get ClassCastException trying to cast ActiveMQConnectionFactory to ActiveMQXAConnectionFactory. Maybe that should work since it's a subclass, but that error makes me doubtful So far I've only been successful with my patch which returns an ActiveMQXAConnectionFactory specifically. From within webMethods, I can set "other properties" which seem to be "jndi.properties." I tried adding "MyConnection" to my custom list of connectionFactoryNames, but I was unsuccessful performing a context.lookup() on "MyConnection.xa=true" or "connection.MyConnection.xa=true" ... If I can get your patch working, I still want to modify the DEFAULT_CONNECTION_FACTORY_NAMES to include "XAConnectionFactory" to make it available as easily as the other standard JMS types. Thanks for your help on this
          Hide
          Edan idzerda added a comment - - edited

          This version is based on the latest svn but adds an XAConnectionFactory to the default list of factories, and sets the "xa" environment value manually for that factory during creation. I was able to test the original patch successfully, and this patch lets me lookup "XAConnectionFactory" via the JNDI context which I believe will be required to easily integrate with webMethods.

          Maybe it should be a regexp so any custom connection name with "XA" will get the treatment? shrug I guess I think that at a minimum, a default connection factory name like "XAConnectionFactory" should work without setting environment variables. But I what do I know, seriously...

          Show
          Edan idzerda added a comment - - edited This version is based on the latest svn but adds an XAConnectionFactory to the default list of factories, and sets the "xa" environment value manually for that factory during creation. I was able to test the original patch successfully, and this patch lets me lookup "XAConnectionFactory" via the JNDI context which I believe will be required to easily integrate with webMethods. Maybe it should be a regexp so any custom connection name with "XA" will get the treatment? shrug I guess I think that at a minimum, a default connection factory name like "XAConnectionFactory" should work without setting environment variables. But I what do I know, seriously...
          Hide
          Gary Tully added a comment -

          If you can specify in other properties:

          connectionFactoryNames=XAConnectionFactory
          xa=true
          

          then:

          context.lookup("XAConnectionFactory")

          will be an instanceof XAConnectionFactory

          Show
          Gary Tully added a comment - If you can specify in other properties: connectionFactoryNames=XAConnectionFactory xa= true then: context.lookup( "XAConnectionFactory" ) will be an instanceof XAConnectionFactory
          Hide
          Edan idzerda added a comment -

          Thanks for the pointers on the properties. I was able to just have a line with "xa=true" in both my jndi.properties for my standalone java client test and the "Other Properties" in webMethods and create an "XA" transaction by just looking up "ConnectionFactory." It seems to apply to all ConnectionFactory lookups, though, so my standalone java client gets an exception when sending a message:

          javax.jms.JMSException: Session's XAResource has not been enlisted in a distributed transaction.

          I assume there is no way to limit the xa=true property to a particular connection factory lookup with this method. (If I use your snippet above a lookup of "ConnectionFactory" fails, for instance.) It seems less desirable to me to be forced into creating separate processes or JNDI Providers in webMethods to do XA or not. But I can work with the patch you have submitted for 5.4.0, as opposed to current. Once we've had a chance to test out the current patch in webMethods more, perhaps we will see if it is a big of a pain or not.

          I'm tempted to keep my patch locally, as it strikes me as much easier to remember "just look up XAConnectionFactory if that's what you need" as opposed to configuring the environment. OTOH, it may be harder to remember to keep my local patch when we upgrade someday Thanks again.

          Show
          Edan idzerda added a comment - Thanks for the pointers on the properties. I was able to just have a line with "xa=true" in both my jndi.properties for my standalone java client test and the "Other Properties" in webMethods and create an "XA" transaction by just looking up "ConnectionFactory." It seems to apply to all ConnectionFactory lookups, though, so my standalone java client gets an exception when sending a message: javax.jms.JMSException: Session's XAResource has not been enlisted in a distributed transaction. I assume there is no way to limit the xa=true property to a particular connection factory lookup with this method. (If I use your snippet above a lookup of "ConnectionFactory" fails, for instance.) It seems less desirable to me to be forced into creating separate processes or JNDI Providers in webMethods to do XA or not. But I can work with the patch you have submitted for 5.4.0, as opposed to current. Once we've had a chance to test out the current patch in webMethods more, perhaps we will see if it is a big of a pain or not. I'm tempted to keep my patch locally, as it strikes me as much easier to remember "just look up XAConnectionFactory if that's what you need" as opposed to configuring the environment. OTOH, it may be harder to remember to keep my local patch when we upgrade someday Thanks again.
          Hide
          Gary Tully added a comment -

          you are nearly there, try

          connectionFactoryNames=XAConnectionFactory,ConnectionFactory
          connection.XAConnectionFactory.xa=true
          

          and you can lookup both an xa and non xa connectonfactory by their respective names.

          Show
          Gary Tully added a comment - you are nearly there, try connectionFactoryNames=XAConnectionFactory,ConnectionFactory connection.XAConnectionFactory.xa= true and you can lookup both an xa and non xa connectonfactory by their respective names.
          Hide
          Edan idzerda added a comment - - edited

          Why didn't you mention that in the first place!?!?! Oh... Because you did... DOH!

          Ok, that is working fine for both my Java client test and our webMethods environment, even as far as verifying a transaction can be rolled back. I still think XAConnectionFactory should be available without additional configuration, for instance, just yesterday I had to remind a coworker to copy the properties configuration after setting up a new system

          But this is working and I don't want to be too pushy with my first reported issue Thanks a lot for the help.

          Show
          Edan idzerda added a comment - - edited Why didn't you mention that in the first place!?!?! Oh... Because you did... DOH! Ok, that is working fine for both my Java client test and our webMethods environment, even as far as verifying a transaction can be rolled back. I still think XAConnectionFactory should be available without additional configuration, for instance, just yesterday I had to remind a coworker to copy the properties configuration after setting up a new system But this is working and I don't want to be too pushy with my first reported issue Thanks a lot for the help.
          Hide
          Nace Sapundziev added a comment -

          Hello Gary and Edan,

          I have the same problem using the XAConnectionFactory with ActiveMQ.
          Could please tell me is this patch released and how can I use it?

          Regards,
          Nace

          Show
          Nace Sapundziev added a comment - Hello Gary and Edan, I have the same problem using the XAConnectionFactory with ActiveMQ. Could please tell me is this patch released and how can I use it? Regards, Nace
          Show
          Gary Tully added a comment - it is in 5.4.0, see the fix version above and the comment: https://issues.apache.org/activemq/browse/AMQ-2656?focusedCommentId=58336&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#action_58336 that has details of the properties. There is also a test you can browse: http://fisheye6.cenqua.com/browse/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/jndi/XAConnectionFactoryTest.java
          Hide
          Nace Sapundziev added a comment -

          Thanks for your fast response Gary. Yes it works for me.

          Thanks again,
          Nace

          Show
          Nace Sapundziev added a comment - Thanks for your fast response Gary. Yes it works for me. Thanks again, Nace
          Hide
          Peter Hinds added a comment - - edited

          Gary, thanks for your help on this. In the end I had to use the version of ActiveMQInitialContextFactory.java as attached by Edan idzerda at 2010-03-18 11:05 PM. I had a search through the ActiveMQ issue tracker and couldn't find if Edan's suggested code was ever added to core - do you know if it was? It would be very useful if it was for cases like the one I have outlined below where the setting up of the jndi environment is abstracted up out of the code. (i.e. in websphere you cannot define the 'xa=true' property anywhere - hence Edan's 'XAConnection' jndi name is invaluable!

          For anybody else trying to get a connection to ActiveMQ within a WebSphere7.0.0-managed XA transaction and getting an error of "An illegal attempt to commit a one phase capable resource with existing two phase capable resources has occured" in the WebSphere SystemOut.log. This error was thrown when a Message Driven Bean was fired from a WebSphere default jms queue and it tried to write a message to an ActiveMQ queue all within an XA transaction. There was an Oracle db write in the same transaction also. Here are the steps to get around it:

          1) Use the attached file kindly attached by Edan at 2010-03-18 11:05 PM to compile activemq-5.4.0.

          2) In WebSphere Admin Console, create a new JMS provider:
          i) Resources > JMS > JMS providers > New
          ii) Use the following:
          Name: use a name like 'ActiveMQ 5.4.0'
          Classpath: add the paths to the following jar files (each path needs to be on a new line in the text box) activemq-all-5.4.0.jar, commons-logging-1.1.jar, geronimo-j2ee-management_1.1_spec-1.0.1.jar
          External Initial Context Factory: org.apache.activemq.jndi.ActiveMQWASInitialContextFactory
          External Provider URL: tcp://localhost:61616

          3) In WebSphere Admin Console, create a new ConnectionFactory
          i) Resources > JMS > Connection factories > New
          ii) Use the following:
          Name: use a name like 'ActiveMQ 5.4.0 Connection Factory'
          JNDI name: jmsfactory/activemq540connfactory (this will be the name that any WebSphere-run apps will lookup using jndi)
          External JNDI name: XAConnectionFactory (this is the new name added by Edan's code in step 1 above - basically, when you're code running in WebSphere calls 'jmsfactory/activemq540connfactory', WebSphere does a call to activemq using this jndi name, i.e. XAConnectionFactory )

          Show
          Peter Hinds added a comment - - edited Gary, thanks for your help on this. In the end I had to use the version of ActiveMQInitialContextFactory.java as attached by Edan idzerda at 2010-03-18 11:05 PM. I had a search through the ActiveMQ issue tracker and couldn't find if Edan's suggested code was ever added to core - do you know if it was? It would be very useful if it was for cases like the one I have outlined below where the setting up of the jndi environment is abstracted up out of the code. (i.e. in websphere you cannot define the 'xa=true' property anywhere - hence Edan's 'XAConnection' jndi name is invaluable! For anybody else trying to get a connection to ActiveMQ within a WebSphere7.0.0-managed XA transaction and getting an error of "An illegal attempt to commit a one phase capable resource with existing two phase capable resources has occured" in the WebSphere SystemOut.log. This error was thrown when a Message Driven Bean was fired from a WebSphere default jms queue and it tried to write a message to an ActiveMQ queue all within an XA transaction. There was an Oracle db write in the same transaction also. Here are the steps to get around it: 1) Use the attached file kindly attached by Edan at 2010-03-18 11:05 PM to compile activemq-5.4.0. 2) In WebSphere Admin Console, create a new JMS provider: i) Resources > JMS > JMS providers > New ii) Use the following: Name: use a name like 'ActiveMQ 5.4.0' Classpath: add the paths to the following jar files (each path needs to be on a new line in the text box) activemq-all-5.4.0.jar, commons-logging-1.1.jar, geronimo-j2ee-management_1.1_spec-1.0.1.jar External Initial Context Factory: org.apache.activemq.jndi.ActiveMQWASInitialContextFactory External Provider URL: tcp://localhost:61616 3) In WebSphere Admin Console, create a new ConnectionFactory i) Resources > JMS > Connection factories > New ii) Use the following: Name: use a name like 'ActiveMQ 5.4.0 Connection Factory' JNDI name: jmsfactory/activemq540connfactory (this will be the name that any WebSphere-run apps will lookup using jndi) External JNDI name: XAConnectionFactory (this is the new name added by Edan's code in step 1 above - basically, when you're code running in WebSphere calls 'jmsfactory/activemq540connfactory', WebSphere does a call to activemq using this jndi name, i.e. XAConnectionFactory )
          Hide
          Gary Tully added a comment -

          @peter, thanks for closing the loop on this with the feeback.
          So in 2.ii or 3.i - there is no possibility to specify an additional property for the jndi environment?
          not good.

          So either we have a hardcoded xaconnection factory, Edan's fix, or the 'xa=true' jndi env property needs to be embedded in the 2.ii external provider url, like tcp://localhost:61616?jndi.xa=true

          Show
          Gary Tully added a comment - @peter, thanks for closing the loop on this with the feeback. So in 2.ii or 3.i - there is no possibility to specify an additional property for the jndi environment? not good. So either we have a hardcoded xaconnection factory, Edan's fix, or the 'xa=true' jndi env property needs to be embedded in the 2.ii external provider url, like tcp://localhost:61616?jndi.xa=true
          Hide
          Peter Hinds added a comment - - edited

          In websphere there are options in 2.ii and 3.i to add what are called 'custom properties' but these do not get translated into jndi environment properties unfortulately.

          In terms of which route to take I would say that the provider url should be left intact. To me it would be more intuitive if the name you supply to a jndi lookup call determines if an ActiveMQXAConnectionFactory or an ActiveMQConnectionFactory is returned as opposed to the provider url used to create the InitialContext. I guess setting it in the provider url abstracts it away from where it is relevant, which is in the jndi lookup call. As in all things though, this is just my opinion - and I'm more than wiling to be corrected!

          Using the 'XAConnectionFactory' jndi name also has the additional benefit of leaving the well recognised url of 'tcp://localhost:61616' untouched as well as being tried and tested - thanks to Edan!!

          Show
          Peter Hinds added a comment - - edited In websphere there are options in 2.ii and 3.i to add what are called 'custom properties' but these do not get translated into jndi environment properties unfortulately. In terms of which route to take I would say that the provider url should be left intact. To me it would be more intuitive if the name you supply to a jndi lookup call determines if an ActiveMQXAConnectionFactory or an ActiveMQConnectionFactory is returned as opposed to the provider url used to create the InitialContext. I guess setting it in the provider url abstracts it away from where it is relevant, which is in the jndi lookup call. As in all things though, this is just my opinion - and I'm more than wiling to be corrected! Using the 'XAConnectionFactory' jndi name also has the additional benefit of leaving the well recognised url of 'tcp://localhost:61616' untouched as well as being tried and tested - thanks to Edan!!
          Hide
          Gary Tully added a comment -

          opening so we don't forget to add a hard coded xa factory name.

          Show
          Gary Tully added a comment - opening so we don't forget to add a hard coded xa factory name.
          Hide
          Gary Tully added a comment -

          URL: http://svn.apache.org/viewvc?rev=1360125&view=rev
          Log:
          https://issues.apache.org/jira/browse/AMQ-2656 - add wellknown xa factory name, XAConnectionFactory so that context.lookup("XAConnectionFactory") will work as expected out of the box

          Show
          Gary Tully added a comment - URL: http://svn.apache.org/viewvc?rev=1360125&view=rev Log: https://issues.apache.org/jira/browse/AMQ-2656 - add wellknown xa factory name, XAConnectionFactory so that context.lookup("XAConnectionFactory") will work as expected out of the box

            People

            • Assignee:
              Gary Tully
              Reporter:
              Edan idzerda
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development