cancel
Showing results for 
Search instead for 
Did you mean: 

Calling EJB from MDB, cannot enlist XA connection

Former Member
0 Kudos

I have a test case that illustrates a problem I have in our application. Our application works in WebLogic and I am porting it to NetWeaver 6.40 on Windows 2003 server (Sp16, web download preview version). I have overcome several issues to date but I've been unable to solve this one after about a week of investigation.

The test case is simply an EAR file which contains two EJBs. A Message Driven Bean with TX_REQUIRED gets a connection from an XA datasource, then it calls an EJB which also has TX_REQUIRED and attempts to get a connection. However, when the EJB attempts to get the connection the thread blocks for a minute or so on DataSource.getConnection() and then an exception is thrown as follows:

#1.5#0019BBCC3906005B0000001B0000192800042F141BE2D5D1#1177663320562#com.sap.engine.services.ts#letsys.com/ChrisApp#com.sap.engine.services.ts#erespond#31#SAP J2EE Engine JTA Transaction : [04b5fffffffe60003d]###06091b90f49b11db8e470019bbcc3906#SAPEngine_Application_Thread[impl:3]_26##0#0#Error#1#/System/Server#Java#ts_0045##Cannot enlist resource:oracle.jdbc.driver.T4CXAResource@1ee8f30 into jta transaction because of XAException from xaResource.start(xid, XAResource.TMJOIN) #1#oracle.jdbc.driver.T4CXAResource@1ee8f30#

#1.5#0019BBCC3906005B0000001C0000192800042F141BE2DDE5#1177663320562#com.sap.engine.services.ts#letsys.com/ChrisApp#com.sap.engine.services.ts#erespond#31#SAP J2EE Engine JTA Transaction : [04b5fffffffe60003d]###06091b90f49b11db8e470019bbcc3906#SAPEngine_Application_Thread[impl:3]_26##0#0#Error#1#/System/Audit#Java###Exception #1#com.sap.engine.services.ts.exceptions.BaseSystemException: Cannot enlist resource:oracle.jdbc.driver.T4CXAResource@1ee8f30 into jta transaction because of XAException from xaResource.start(xid, XAResource.TMJOIN) at com.sap.engine.services.ts.jta.impl.TransactionImpl.enlistResource(TransactionImpl.java:592) at com.sap.engine.services.connector.resource.impl.ResourceSetImpl.addAndEnlist(ResourceSetImpl.java:263) at com.sap.engine.services.connector.jca.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:241) at com.sap.engine.services.dbpool.cci.ConnectionFactoryImpl.getConnection(ConnectionFactoryImpl.java:51) at helloejb.HelloBean.sayHello(HelloBean.java:36) at helloejb.HelloLocalLocalObjectImpl0.sayHello(HelloLocalLocalObjectImpl0.java:115) at helloejb.HelloMDBean.onMessage(HelloMDBean.java:39) at helloejb.HelloMDBean0Extension._onMessage(HelloMDBean0Extension.java:163) at helloejb.HelloMDBean0Extension.run(HelloMDBean0Extension.java:39) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Subject.java:379) at helloejb.HelloMDBean0Extension.onMessage(HelloMDBean0Extension.java:141) at com.sap.jms.client.session.Session.run(Session.java:581) at com.sap.engine.services.jmsconnector.cci.SessionImpl.run(SessionImpl.java:216) at com.sap.engine.services.ejb.message.RunnableObject.run(RunnableObject.java:49) at com.sap.engine.core.thread.impl3.ActionObject.run(ActionObject.java:37) at java.security.AccessController.doPrivileged(Native Method) at com.sap.engine.core.thread.impl3.SingleThread.execute(SingleThread.java:100) at com.sap.engine.core.thread.impl3.SingleThread.run(SingleThread.java:170) Caused by: oracle.jdbc.xa.OracleXAException at oracle.jdbc.xa.OracleXAResource.checkError(OracleXAResource.java:938) at oracle.jdbc.xa.client.OracleXAResource.start(OracleXAResource.java:244) at com.sap.engine.services.ts.jta.impl.TransactionImpl.enlistResource(TransactionImpl.java:582) ... 18 more # #1.5#0019BBCC3906005B0000001D0000192800042F141BE2EB12#1177663320562#com.sap.engine.services.connector.resource.impl.HandleWrapper#letsys.com/ChrisApp#com.sap.engine.services.connector.resource.impl.HandleWrapper#erespond#31#SAP J2EE Engine JTA Transaction : [04b5fffffffe60003d]###06091b90f49b11db8e470019bbcc3906#SAPEngine_Application_Thread[impl:3]_26##0#0#Error##Java### [EXCEPTION] #1#com.sap.engine.services.connector.exceptions.BaseResourceException: Error in ResourceSet.addAndEnlist("com.sap.engine.services.connector.resource.impl.HandleWrapper@16b2d22[com.sap.engine.services.dbpool.cci.ConnectionHandle@1b174cc](delisted:false) -> com.sap.engine.services.connector.resource.impl.MCEventHandler@16a2d04 --> 8(locTrSupp:false)").

at com.sap.engine.services.connector.jca.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:244)

at com.sap.engine.services.dbpool.cci.ConnectionFactoryImpl.getConnection(ConnectionFactoryImpl.java:51)

at helloejb.HelloBean.sayHello(HelloBean.java:36)

at helloejb.HelloLocalLocalObjectImpl0.sayHello(HelloLocalLocalObjectImpl0.java:115)

at helloejb.HelloMDBean.onMessage(HelloMDBean.java:39)

at helloejb.HelloMDBean0Extension._onMessage(HelloMDBean0Extension.java:163)

at helloejb.HelloMDBean0Extension.run(HelloMDBean0Extension.java:39)

at java.security.AccessController.doPrivileged(Native Method)

at javax.security.auth.Subject.doAs(Subject.java:379)

at helloejb.HelloMDBean0Extension.onMessage(HelloMDBean0Extension.java:141)

at com.sap.jms.client.session.Session.run(Session.java:581)

at com.sap.engine.services.jmsconnector.cci.SessionImpl.run(SessionImpl.java:216)

at com.sap.engine.services.ejb.message.RunnableObject.run(RunnableObject.java:49)

at com.sap.engine.core.thread.impl3.ActionObject.run(ActionObject.java:37)

at java.security.AccessController.doPrivileged(Native Method)

at com.sap.engine.core.thread.impl3.SingleThread.execute(SingleThread.java:100)

at com.sap.engine.core.thread.impl3.SingleThread.run(SingleThread.java:170)

Caused by: com.sap.engine.services.ts.exceptions.BaseSystemException: Cannot enlist resource:oracle.jdbc.driver.T4CXAResource@1ee8f30 into jta transaction because of XAException from xaResource.start(xid, XAResource.TMJOIN)

at com.sap.engine.services.ts.jta.impl.TransactionImpl.enlistResource(TransactionImpl.java:592)

at com.sap.engine.services.connector.resource.impl.ResourceSetImpl.addAndEnlist(ResourceSetImpl.java:263)

at com.sap.engine.services.connector.jca.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:241)

... 16 more

Caused by: oracle.jdbc.xa.OracleXAException

at oracle.jdbc.xa.OracleXAResource.checkError(OracleXAResource.java:938)

at oracle.jdbc.xa.client.OracleXAResource.start(OracleXAResource.java:244)

at com.sap.engine.services.ts.jta.impl.TransactionImpl.enlistResource(TransactionImpl.java:582)

... 18 more

As far as I can figure out, the exception is thrown when the driver calls JAVA_XA.xa_start_new(?,?,?,?,?) and Oracle returns a primary error code of 25351 which is:

ORA-25351: transaction attached to some other session

Cause: The user transaction is currently used by others.

Action: Do not switch to a transaction attached to some other session.

Test case code follows, any advice would be much appreciated as I've tried almost everything I can think of at this stage.

Note that the test case works if I set the Session EJB to be TX_REQUIRES_NEW

META-INF/applicaiton.xml

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE application PUBLIC "-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN" "http://java.sun.com/dtd/application_1_3.dtd">

<application>

<display-name>ChrisApp</display-name>

<module>

<ejb>helloejb.jar</ejb>

</module>

</application>

META-INF/application-j2ee-engine.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE application-j2ee-engine SYSTEM "application-j2ee-engine.dtd">

<application-j2ee-engine>

<provider-name>letsys.com</provider-name>

<fail-over-enable mode="disable"/>

</application-j2ee-engine>

META-INF/jms-factories.xml

<jms-factories>

<application-name>ChrisApp</application-name>

<connection-factory>

<factory-name>ChrisXAQueueConnectionFactory</factory-name>

<context-factory-type>

<link-factory-name>jmsfactory/default/ChrisXAQueueConnectionFactory</link-factory-name>

<initial-context-factory>

com.sap.engine.services.jndi.InitialContextFactoryImpl

</initial-context-factory>

<provider-url>localhost</provider-url>

<security-principal>

Administrator

</security-principal>

<security-credentials>

</security-credentials>

</context-factory-type>

</connection-factory>

</jms-factories>

Session EJB class

package helloejb;

import java.rmi.RemoteException;

import java.sql.Connection;

import java.sql.SQLException;

import javax.ejb.*;

import javax.naming.InitialContext;

import javax.sql.DataSource;

public class HelloBean implements SessionBean {

protected SessionContext sc = null;

public void ejbCreate() {

}

public void setSessionContext(SessionContext sessionContext) throws EJBException, RemoteException {

sc = sessionContext;

}

public void ejbActivate() throws EJBException, RemoteException {

}

public void ejbPassivate() throws EJBException, RemoteException {

}

public void ejbRemove() throws EJBException, RemoteException {

}

public void sayHello() {

Connection con = null;

System.err.println("sayHello()....");

try {

System.err.println("sayHello()....!!!!!!!!!!!!!!***getConnection***!!!!!!!!!!!!!!!!!!!!!!!!!!!!");

con = ((DataSource) new InitialContext().lookup("jdbc/managedTxXA")).getConnection();

System.err.println("sayHello()....!!!!!!!!!!!!!!!!!!WORKED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");

} catch (Exception e) {

System.err.println("sayHello()....!!!!!!!!!!!!!!!!!!FAILED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");

e.printStackTrace();

throw new RuntimeException(e);

} finally {

if (con != null) {

try { con.close(); }catch(SQLException e){e.printStackTrace();

}

}

}

}

}

MDB class

package helloejb;

import javax.ejb.MessageDrivenBean;

import javax.ejb.MessageDrivenContext;

import javax.ejb.EJBException;

import javax.jms.MessageListener;

import javax.jms.Message;

import javax.naming.InitialContext;

import javax.sql.DataSource;

import java.sql.Connection;

import java.sql.SQLException;

public class HelloMDBean implements MessageDrivenBean, MessageListener {

public void ejbCreate() {

}

public void setMessageDrivenContext(MessageDrivenContext messageDrivenContext) throws EJBException {

}

public void ejbRemove() throws EJBException {

}

public void onMessage(Message message) {

Connection con = null;

try {

System.err.println("In onMessage()");

HelloLocalHome home = (HelloLocalHome) (new InitialContext().lookup("java:comp/env/ejb/HelloLocal"));

con = ((DataSource) new InitialContext().lookup("jdbc/managedTxXA")).getConnection();

HelloLocal local = home.create();

local.sayHello();

} catch (Exception e) {

throw new RuntimeException(e);

} finally {

if (con != null) {

try {

con.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

}

}

}

ejb/META-INF/ejb-jar.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">

<ejb-jar>

<description>Description</description>

<display-name>Description</display-name>

<enterprise-beans>

<session>

<display-name>Hello</display-name>

<ejb-name>Hello</ejb-name>

<home>helloejb.HelloHome</home>

<remote>helloejb.HelloRemote</remote>

<local-home>helloejb.HelloLocalHome</local-home>

<local>helloejb.HelloLocal</local>

<ejb-class>helloejb.HelloBean</ejb-class>

<session-type>Stateless</session-type>

<transaction-type>Container</transaction-type>

<resource-ref>

<res-ref-name>jdbc/managedTxXA</res-ref-name>

<res-type>javax.sql.DataSource</res-type>

<res-auth>Container</res-auth>

</resource-ref>

</session>

<message-driven>

<description><![CDATA[]]></description>

<ejb-name>HelloMD</ejb-name>

<ejb-class>helloejb.HelloMDBean</ejb-class>

<transaction-type>Container</transaction-type>

<acknowledge-mode>Auto-acknowledge</acknowledge-mode>

<message-driven-destination>

<destination-type>javax.jms.Queue</destination-type>

</message-driven-destination>

<!<ejb-local-ref>>

<!<ejb-ref-name>ejb/Hello</ejb-ref-name>>

<!<ejb-ref-type>Session</ejb-ref-type>>

<!<local-home >helloejb.HelloHome</local-home>>

<!<local>helloejb.Hello</local>>

<!<ejb-link>helloejb.Hello</ejb-link>>

<!</ejb-local-ref>>

<ejb-ref>

<ejb-ref-name>ejb/HelloRemote</ejb-ref-name>

<ejb-ref-type>Session</ejb-ref-type>

<home>helloejb.HelloHome</home>

<remote>helloejb.HelloRemote</remote>

<ejb-link>Hello</ejb-link>

</ejb-ref>

<ejb-local-ref>

<ejb-ref-name>ejb/HelloLocal</ejb-ref-name>

<ejb-ref-type>Session</ejb-ref-type>

<local-home>helloejb.HelloLocalHome</local-home>

<local>helloejb.HelloLocal</local>

<ejb-link>Hello</ejb-link>

</ejb-local-ref>

<security-identity>

<run-as>

<role-name>eRespondSystem</role-name>

</run-as>

</security-identity>

</message-driven>

</enterprise-beans>

<assembly-descriptor>

<container-transaction>

<method>

<ejb-name>Hello</ejb-name>

<method-name>*</method-name>

</method>

<trans-attribute>Required</trans-attribute>

</container-transaction>

<container-transaction>

<method>

<ejb-name>HelloMD</ejb-name>

<method-name>*</method-name>

</method>

<trans-attribute>Required</trans-attribute>

</container-transaction>

</assembly-descriptor>

</ejb-jar>

ejb-j2ee-engine.xml

<ejb-j2ee-engine>

<enterprise-beans>

<enterprise-bean>

<ejb-name>HelloMD</ejb-name>

<message-props>

<destination-name>helloMDqueue</destination-name>

<connection-factory-name>ChrisXAQueueConnectionFactory</connection-factory-name>

</message-props>

<run-as-identity-map>

<user-name>erespond</user-name>

</run-as-identity-map>

</enterprise-bean>

</enterprise-beans>

</ejb-j2ee-engine>

Test Client

public static void main(String args[]) throws Exception {

Context context = EJBUtil.getContext();

QueueConnectionFactory connectionFactory = (QueueConnectionFactory) context.lookup("jmsfactory/default/XAQueueConnectionFactory");

QueueConnection queueConnection = connectionFactory.createQueueConnection();

queueConnection.start();

QueueSession qsession = queueConnection.createQueueSession(true, Session.AUTO_ACKNOWLEDGE);

Queue q = (Queue) EJBUtil.getContext().lookup("jmsqueues/default/helloMDqueue");

QueueSender qSender = qsession.createSender(q);

TextMessage textMsg = qsession.createTextMessage();

textMsg.setText("Test JMS msg");

qSender.send(textMsg);

Thread.sleep(20000);

qsession.commit();

qsession.close();

}

Accepted Solutions (0)

Answers (1)

Answers (1)

Former Member
0 Kudos

I can provide a test ear if anyone wants to run my testcase.

Former Member
0 Kudos

Ok, I retested this on 6.40 SP19 and it works as expected, along with a few other problems I had. The sneak preview is buggy, don't waste your time on it if you have the option of using an official version. It is very useful for initial porting work but not for much more than that.

I hope this saves somebody some time.

Chris.