ActiveMQ XA subscriber unknown XAResource

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

ActiveMQ XA subscriber unknown XAResource

bswamina
I am exploring BTM and when I tried the following test code I get:

bitronix.tm.internal.BitronixSystemException: unknown XAResource org.apache.activemq.TransactionContext@2200d5, it does not belong to a registered resource

Any ideas on what I am doing wrong ?

----------------------------- Code -------------------------------

import javax.jms.*;
import javax.jms.Message;
import javax.transaction.*;

import bitronix.tm.*;

import org.apache.activemq.*;

public class MyTestAmqXaSubscriber {
        static TransactionManager manager = null;

        public static void main(final String[] args) {
                if (args.length != 1) {
                        System.out.printf("Usage: java %s <id>\n", MyTestAmqXaSubscriber.class.getName());
                        System.exit(1);
                }
                try {
                        init();
                        process(Integer.parseInt(args[0]));
                }
                catch (final Exception ex) {
                        ex.printStackTrace(System.err);
                }
        }
       
        static void init()
                throws Exception {
                final Configuration conf = TransactionManagerServices.getConfiguration();
                conf.setServerId("amq-1");
                conf.setLogPart1Filename("./xa_sub1.tlog");
                conf.setLogPart2Filename("./xa_sub2.tlog");
       
                manager = TransactionManagerServices.getTransactionManager();
        }

        static void process(final int id) {
                for (;;) {
                        try {
                                manager.begin();
                               
                                final XAConnectionFactory factory = new ActiveMQXAConnectionFactory("tcp://localhost:61616");

                                final XAConnection connection = factory.createXAConnection();
                                connection.start();

                                final XASession session = connection.createXASession();
                               
                                manager.getTransaction().enlistResource(session.getXAResource());

                                final Topic topic = session.createTopic("my.amq.xa.topic");

                                final TopicSubscriber subscriber = session.createDurableSubscriber(topic, "MyTestXaSubscriber-"+id);

                                final Message msg = subscriber.receive();

                                final String line = ((TextMessage)msg).getText();

                                System.out.printf("Consumed message ->%s<-\n", line);

                                manager.commit();

                                subscriber.close();

                                session.close();

                                connection.close();
                        }
                        catch (final Exception ex) {
                                ex.printStackTrace(System.err);

                                try {
                                        manager.rollback();
                                }
                                catch (final Exception e) {
                                        e.printStackTrace(System.err);
                                }
                        }
                }
        }
}
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ActiveMQ XA subscriber unknown XAResource

bswamina
After digging through the source code of the BitronixTransaction realized that it is expecting a PoolingConnectionFactory. Is there a technical reason why it has to be Pool other than the reason that inside a container we can have multiple transactions in flight.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ActiveMQ XA subscriber unknown XAResource

Ludovic Orban
Administrator
Hi (and sorry for the late response),

In a nutshell, yes, BTM expects you to configure and use a PoolingConnectionFactory to get JMS access. There are multiple benefits to that: you get connection pooling and caching plus automatic enlistment in the transaction and that's completely transparent.

In theory you could directly make use of the vendor's XAConnectionFactory and perform manual enlistment, exactly like you're doing. In practice, if you want to enlist a XAResource then BTM mandates being able to trace back the XAResource to the object which has been used to produce it. This is required for the recovery: BTM will not allow a resource to participate in a transaction if it cannot guarantee that it will be able to recover it in case of crash.

This is the reason why you get this 'BitronixSystemException unknown XAResource xyz, it does not belong to a registered resource' error: because BTM does no know about that XAResource so it rejects it.

In short, there is IMHO no reason not to use the provided JDBC and JMS pools as they're reasonably easy to configure and handle all the gory details.
DY
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ActiveMQ XA subscriber unknown XAResource

DY
Hi Ludovic,
I found your reply very helpful but still have couple questions around it.
We did PoolingConnectionFactory configuration at Tomcat with changing resource.properties & context.xml files.
resource.properties:
resource.mq1.className=org.apache.activemq.ActiveMQXAConnectionFactory
resource.mq1.uniqueName=activemq
resource.mq1.maxPoolSize=5
resource.mq1.minPoolSize=3
resource.mq1.driverProperties.brokerURL=tcp\://localhost\:61616

context.xml:
<Resource auth="Container" factory="bitronix.tm.resource.ResourceObjectFactory" name="activemq" type="javax.jms.XAConnectionFactory" uniqueName="activemq"/>

And I can see that it was registered with bitronix.tm.resource.ResourceLoader
Now, I can acces PoolingConnectionFactory via initial context lookup in my code. But the problem is that PoolingConnectionFactory is an instance of ConnectionFactory, however I need to obtain XAConnectionFactory. The reason I need XAConnectionFactory is that I want to obtain XAResource(factory->connection->session->xaresource) and use it to enlist/delist with my transaction manually.
Are there any way to obtain XAResource? The only way I found so far is cast connection to JmsConnectionHandle and use getXAConnection() method with it, but that looks ugly.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ActiveMQ XA subscriber unknown XAResource

Ludovic Orban-2
Why do you want to access the XAResource? This object is meant to be used internally by the TM which explains why it's not readily accessible.

If what you're looking to do is enlist the XAResource, again why do you want to do it when the PoolingConnectionFactory can do it for you automatically and at the best possible time?

Le vendredi 29 mars 2013, DY a écrit :
Hi Ludovic,
I found your reply very helpful but still have couple questions around it.
We did PoolingConnectionFactory configuration at Tomcat with changing
resource.properties & context.xml files.
resource.properties:
resource.mq1.className=org.apache.activemq.ActiveMQXAConnectionFactory
resource.mq1.uniqueName=activemq
resource.mq1.maxPoolSize=5
resource.mq1.minPoolSize=3
resource.mq1.driverProperties.brokerURL=tcp\://localhost\:61616

context.xml:
<Resource auth="Container"
factory="bitronix.tm.resource.ResourceObjectFactory" name="activemq"
type="javax.jms.XAConnectionFactory" uniqueName="activemq"/>

And I can see that it was registered with
bitronix.tm.resource.ResourceLoader
Now, I can acces PoolingConnectionFactory via initial context lookup in my
code. But the problem is that PoolingConnectionFactory is an instance of
ConnectionFactory, however I need to obtain XAConnectionFactory. The reason
I need XAConnectionFactory is that I want to obtain
XAResource(factory->connection->session->xaresource) and use it to
enlist/delist with my transaction manually.
Are there any way to obtain XAResource? The only way I found so far is cast
connection to JmsConnectionHandle and use getXAConnection() method with it,
but that looks ugly.



--
View this message in context: http://bitronix-transaction-manager.10986.n7.nabble.com/ActiveMQ-XA-subscriber-unknown-XAResource-tp225p1450.html
Sent from the Bitronix Transaction Manager mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


DY
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ActiveMQ XA subscriber unknown XAResource

DY
Do you mean that PoolingConnectionFactory will do it automatically with the following setting?
resource.mq1.automaticEnlistingEnabled=true
Well, it's a legacy application which is working with other app servers and now we are trying to run it on Tomcat with BTM. That is why it is preferable to keep using XAResource object.
Loading...