I have an MDB in WebSphere 6. The MessageListener is linked to a Tibco EMS queue. In the MDB I'm trying to write to a WebSphere MQ queue. I get the following error:
WMSG0042I: MDB Listener LoanIQ Payments Inbound started successfully for JMSDestination jms/eid/payments
WTRN0063E: An illegal attempt to commit a one phase capable resource with existing two phase capable resources has occurred.
WTRN0086I: XAException encountered during prepare phase for transaction 00000131...0001. Local resources follow.
WTRN0089I: XATransactionWrapper@ 3fbe3fbe XAResource: com.ibm.ejs.jms.JMSManagedSession$JMSXAResource@3fb83fb8 enlisted: true mcWrapper.hashCode()1038237154: Vote: commit.
WTRN0089I: LocalTransactionWrapper@:4e2e4e2e LocalTransaction:com.ibm.ejs.jms.JMSManagedSession$JMS LocalTransaction@4e5a4e5a enlisted:true registeredForSynctruemcWrapper.hashcode()1032076676: Vote: none.
The QueueConnectionFactory instance is a com.ibm.ejs.jms.JMSQueueConnectionFactoryHandle
. Could I get an XAConnection from this? Do I need to? I'd prefer to stay with vanilla JMS if possible.
The MDB implementation is akin to:
public void onMessage(Message message) {
// ^^ incoming message delivered from EMS queue via WAS MessageListener
TextMessage textMessage = (TextMessage) message;
QueueConnectionFactory factory = (QueueConnectionFactory) context.lookup(factoryName);
Queue queue = (Queue) context.lookup(queueName);
QueueConnection connection = factory.createQueueConnection();
connection.start();
QueueSession session = connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
QueueSender sender = session.createSender(queue);
TextMessage message = session.createTextMessage("some new payload");
sender.send(message);
// ^^ outgoing message sent to WebSphere MQ queue
}
Looking at the error, you have one XA resource and one JCA LocalTransaction
WTRN0089I: XATransactionWrapper@ 3fbe3fbe XAResource: com.ibm.ejs.jms.JMSManagedSession$JMSXAResource@3fb83fb8 enlisted: true mcWrapper.hashCode()1038237154: Vote: commit.
and
WTRN0089I: LocalTransactionWrapper@:4e2e4e2e LocalTransaction:com.ibm.ejs.jms.JMSManagedSession$JMS LocalTransaction@4e5a4e5a enlisted:true registeredForSynctruemcWrapper.hashcode()1032076676: Vote: none.
Sounds like you either haven't set the ConnectionFactory to XA enabled, see:
(scroll down to "XA Enabled") or the Tibco EMS connection isn't XA capable. If it's the latter, and there is no suitable XA driver, then you could look at Last-Participant support in the WAS infocentre, that might do what you need - i.e. WAS would prepare the WMQ XA transaction, locally commit the Tibco, then commit WMQ if the Tibco commit worked (or rollback otherwise). If the Tibco connection is XA capable, then WAS has full XA support for WMQ built in, so there's no reason not to use a two-phase transaction for the whole operation.
Regarding
The QueueConnectionFactory instance is a com.ibm.ejs.jms.JMSQueueConnectionFactoryHandle. Could I get an XAConnection from this? Do I need to? I'd prefer to stay with vanilla JMS if possible.
You shouldn't do this, just keep to plain JMS. As a general point of style it's better to cast to a ConnectionFactory (not QueueConnectionFactory) too, and then remain with cross-domain objects (Connection, Session, MessageProducer).