0

I have configured XADatasource in wildlfy server as I need to use JTA transactions and need to manage multiple databases using the JTATransactionManager using Atomikos implementation. I am getting the below ClassCastException while looking up and builing the AtomikosDatasource using spring boot. It seems the JNDI lookup always returns WildflyDatasource and it does not implement the XADatasource. Please suggest me how to get XADatasource rather than WildflyDatasource when we lookup or to convert from WildlfyDatasource to XADatasource.

Caused by: java.lang.ClassCastException: org.jboss.as.connector.subsystems.datasources.WildFlyDataSource cannot be cast to javax.sql.XADataSource

Below is the snippet to lookup datasource and create AtomikosDataSourceBean

*@Bean(name = "customerDataSource", initMethod = "init", destroyMethod = "close")
@Primary
public DataSource customerDataSource() throws NamingException {     
    JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
    XADataSource mysqlXaDataSource =  (XADataSource) dataSourceLookup.getDataSource("java:/jdbc/atomikos_one");
    AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
    xaDataSource.setXaDataSource(mysqlXaDataSource);        
    xaDataSource.setUniqueResourceName("xads1");
    return xaDataSource;
}*

The below is the datasource configuration in Wildfly 10.1.0.Final

    <xa-datasource jndi-name="java:/jdbc/atomikos_one" pool-name="atomikos_one" enabled="true" use-ccm="true">
                <xa-datasource-property name="ServerName">
                    localhost
                </xa-datasource-property>
                <xa-datasource-property name="DatabaseName">
                    atomikos_one
                </xa-datasource-property>
                <driver>mysql</driver>
                <xa-pool>
                    <min-pool-size>5</min-pool-size>
                    <max-pool-size>100</max-pool-size>
                    <use-strict-min>true</use-strict-min>
                    <wrap-xa-resource>false</wrap-xa-resource>
                </xa-pool>
                <security>
                    <user-name>root</user-name>
                    <password>password</password>
                </security>
                <validation>
                    <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLValidConnectionChecker"/>
                    <background-validation>true</background-validation>
                    <exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLExceptionSorter"/>
                </validation>
            </xa-datasource>
            <driver name="mysql" module="com.mysql">
                <driver-class>com.mysql.jdbc.Driver</driver-class>
                <xa-datasource-class>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</xa-datasource-class>
            </driver>
Srinivas
  • 301
  • 1
  • 2
  • 6

1 Answers1

0

Got it working. I have realized that built-in JTA TransactionManagers are already available in the application server and using it rather than going for the custom implementation of it(Atomikos). Coming to the answer for this question, we can still configure the XADatasoruce in the application server and lookup using JNDI and typecast it to normal Datasource and inject it to EntityManager. The mysqlXaDataSource will still be holding the reference to the XA-Datasource even though the type is Datasource.

The below is the snippet to show how is it working now.


@Bean(name = "customerDataSource", initMethod = "init", destroyMethod = "close")
@Primary
public DataSource customerDataSource() throws NamingException {     
    JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
    DataSource mysqlXaDataSource =  (DataSource ) dataSourceLookup.getDataSource("java:/jdbc/jta_datasource_one");

    return mysqlXaDataSource;
}


LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setJtaDataSource(customerDataSource());
Srinivas
  • 301
  • 1
  • 2
  • 6