0

I am trying to get XA transactions to work on a TomEE server for an Oracle DB. Using AtomikOS transaction manager via Spring configs. I used the example from atomikos documentation https://www.atomikos.com/Documentation/SpringIntegration

On server startup I see below exception as a result the xa connection pool is not created.

SEVERE: Unable to create initial connections of pool.
java.sql.SQLException: oracle.jdbc.xa.client.OracleXADataSource cannot be cast to java.sql.Driver
        at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:254)
        at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:182)
        at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:710)
        at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:644)
        at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:466)
        at org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:143)
        at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:116)
        at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:103)
        at org.apache.tomcat.jdbc.pool.DataSourceFactory.createDataSource(DataSourceFactory.java:554)
        at org.apache.tomcat.jdbc.pool.DataSourceFactory.getObjectInstance(DataSourceFactory.java:242)
        at org.apache.naming.factory.ResourceFactory.getObjectInstance(ResourceFactory.java:141)
        at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321)
        at org.apache.naming.NamingContext.lookup(NamingContext.java:842)
        at org.apache.naming.NamingContext.lookup(NamingContext.java:167)
        at org.apache.tomee.catalina.OpenEJBNamingContextListener.bindResource(OpenEJBNamingContextListener.java:266)
        at org.apache.tomee.catalina.OpenEJBNamingContextListener.addResource(OpenEJBNamingContextListener.java:256)
        at org.apache.tomee.catalina.OpenEJBNamingContextListener.processInitialNamingResources(OpenEJBNamingContextListener.java:223)
        at org.apache.tomee.catalina.OpenEJBNamingContextListener.start(OpenEJBNamingContextListener.java:92)
        at org.apache.tomee.catalina.OpenEJBNamingContextListener.lifecycleEvent(OpenEJBNamingContextListener.java:74)
        at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
        at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
        at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:394)
        at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:339)
        at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:731)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
        at org.apache.catalina.startup.Catalina.start(Catalina.java:693)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:294)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:428)
Caused by: java.lang.ClassCastException: oracle.jdbc.xa.client.OracleXADataSource cannot be cast to java.sql.Driver
        at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:246)
        ... 31 more

Data source configuration and Spring beans as shown below.

<Resource
     name="xads"
         auth="Container"
         type="javax.sql.XADataSource"
         factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
         driverClassName="oracle.jdbc.xa.client.OracleXADataSource"
         url="url"
         username="user"
         password="password"
                 accessToUnderlyingConnectionAllowed="true"
                 maxTotal="10"
                 maxIdle="1"
                 maxWaitMillis="10000"
                 testWhileIdle="true"
                 validationQuery="select 1 from dual"
 />

<bean id="AtomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close">
        <property name="forceShutdown" value="false" />
</bean>

<bean id="AtomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
        <property name="transactionTimeout" value="300" />
</bean>

<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="transactionManager" ref="AtomikosTransactionManager" />
        <property name="userTransaction" ref="AtomikosUserTransaction" />
</bean>

I also tried changing driverClassName="oracle.jdbc.xa.client.OracleXADataSource" to driverClassName="oracle.jdbc.OracleDriver" but then the transactions do not actually join.

I saw a similar post at https://grokbase.com/t/tomcat/users/117czb4yf0/tomcat-pool-and-xa-datasource but the suggested blog (http://www.tomcatexpert.com/blog/2010/04/01/configuring-jdbc-pool-high-concurrency) to fix the issue is no longer valid and redirects to https://tomcat.apache.org/

I expect the xa datasource to join to other transactions and do a two way commit.

  • Where do you use the datasource? Add that part of the configuration as well. – manish Jan 09 '19 at 08:22
  • Its being used to create initial connection pool and the datasource is being looked up as a jndi from applicationContext.xml – QuestToLearn Jan 09 '19 at 15:32
  • The problem is, it fails to even create the initial connection pool at the time of server startup, this should be the only config it must use for connection pooling on server startup. – QuestToLearn Jan 09 '19 at 15:49
  • I meant to ask, where in the Spring configuration do you use the datasource? – manish Jan 10 '19 at 05:32

0 Answers0