Atomikos、Tomcat、JTA java.lang.ClassCastException

Atomikos、Tomcat、JTA java.lang.ClassCastException,tomcat,jms,jta,xa,atomikos,Tomcat,Jms,Jta,Xa,Atomikos,尝试使用Tomcat、Atomikos、ActiveMQ和MySql使事务正常工作。下面是这些例子: 但是没有成功 ERROR: com.atomikos.icatch.jta.UserTransactionManager cannot be cast to javax.transaction.TransactionManager java.lang.ClassCastException: com.atomikos.icatch.jta.UserTransactionManager cannot

尝试使用Tomcat、Atomikos、ActiveMQ和MySql使事务正常工作。下面是这些例子: 但是没有成功

ERROR: com.atomikos.icatch.jta.UserTransactionManager cannot be cast to javax.transaction.TransactionManager
java.lang.ClassCastException: com.atomikos.icatch.jta.UserTransactionManager cannot be cast to javax.transaction.TransactionManager
使用:

  • Tomcat 7.0.29
  • Atomikos 3.7.1
  • ActiveMQ 5.8.0
  • MySQL 5.5.31
在$TOMCAT_HOME/lib下删除以下jar

  • atomikos-integration-extension-3.7.1-20120529.jar
  • atomikos-util-3.7.1.jar
  • 事务-3.7.1.jar
  • transactions-api-3.7.1.jar
  • transactions-jdbc-3.7.1.jar
  • 事务-jms-3.7.1.jar
  • 事务-jta-3.7.1.jar
  • geronimo-jta_1.0.1B_spec-1.0.jar
  • activemq-all-5.8.0.jar
  • mysql-connector-java-5.1.25.jar
以下是transactions.properties的内容

com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory
com.atomikos.icatch.automatic_resource_registration=true
com.atomikos.icatch.output_dir=../work/atomikos
com.atomikos.icatch.log_base_dir=../work/atomikos/log
com.atomikos.icatch.enable_logging=true
com.atomikos.icatch.console_log_level=TRACE
context.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <Context>
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <Transaction factory="com.atomikos.icatch.jta.UserTransactionFactory" />

    <Resource name="TransactionManager"
          auth="Container"
          type="com.atomikos.icatch.jta.UserTransactionManager"
          factory="org.apache.naming.factory.BeanFactory" />

    <Resource name="UserTransaction"
          auth="Container"
          type="com.atomikos.icatch.jta.UserTransactionImp"
          factory="org.apache.naming.factory.BeanFactory" />                 

    <Resource name="jms/ConnectionFactory"
            auth="Container"
            description="JMS Connection Factory"
            type="com.atomikos.jms.AtomikosConnectionFactoryBean"
            factory="com.atomikos.tomcat.EnhancedTomcatAtomikosBeanFactory"
            uniqueResourceName="jms/ConnectionFactory"
            xaConnectionFactoryClassName="org.apache.activemq.ActiveMQXAConnectionFactory"
            xaProperties.brokerURL="vm://localhost"
            xaProperties.transportType="1"
            localTransactionMode="true" />

    <Resource name="jms/WsTopic" 
          auth="Container"
          type="org.apache.activemq.command.ActiveMQTopic" 
          factory="org.apache.activemq.jndi.JNDIReferenceFactory"
          physicalName="WS.TOPIC" />

    <Resource name="jms/WsQueue" 
          auth="Container"
          type="org.apache.activemq.command.ActiveMQQueue"
          factory="org.apache.activemq.jndi.JNDIReferenceFactory" 
          physicalName="WS.QUEUE" />


   <!--  MySQL -->
   <Resource name="jdbc/DB"
          auth="Container"
          type="com.atomikos.jdbc.AtomikosDataSourceBean"
          factory="com.atomikos.tomcat.EnhancedTomcatAtomikosBeanFactory"
          uniqueResourceName="jdbc/DB"
          minPoolSize="5"
          maxPoolSize="10"
          testQuery="SELECT 1 FROM DUAL"             
          xaDataSourceClassName="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"
          xaProperties.databaseName="db"
          xaProperties.serverName="localhost"
          xaProperties.port="3306"
          xaProperties.user="user"
          xaProperties.password="password"
          xaProperties.url="jdbc:mysql://localhost:3306/db"
          xaProperties.pinGlobalTxToPhysicalConnection="true"
          xaProperties.autoReconnect="true"
          xaProperties.autoReconnectForConnectionPools="true"
          xaProperties.autoReconnectForPools="true" />
</Context>
Tomcat使用。请参阅,它是如何工作的,以及哪个优先(引导、系统、webapp、通用)。我假设您将
geronimo-jta_1.0.1B_spec-1.0.jar
和/或
transactions-jta-3.7.1.jar
放在WAR文件
webapp.WAR/WEB-INF/lib/
中,另外还有
$TOMCAT_HOME/lib/
。这可能会导致问题,因为不同的类加载器将多次加载
javax.transaction.TransactionManager
类。即使类具有相同的名称,如果它由不同的类加载器加载,转换也会失败

  • 当TOMCAT初始化由
    com.atomikos.icatch.jta.UserTransactionManager
    实现的
    context.xml
    中定义的容器范围的TransactionManager资源时,首先使用公共类加载器($TOMCAT_HOME/lib/*.jar)加载它。(Tomcat目前不使用任何webapp类加载器。)

  • 您在web应用程序中使用
    javax.transaction.TransactionManager
    类,现在它将从war文件中
    webapp.war/web-INF/lib/
    文件夹中的JAR文件副本加载webapp类加载器

  • 尝试从
    webapp.war/WEB-INF/lib/
    中删除包含
    javax.transaction.TransactionManager
    类的JAR文件,并尝试重新部署应用程序


    或者,在
    CLASSPATH
    系统变量中列出这些JAR文件,这样这些类将由在Tomcat中具有优先权的系统类装入器装入

    谢谢你的详细回复。activemq-all-5.8.0.jar已从webapp.war/WEB-INF/lib/移动到$TOMCAT_HOME/lib/。但是现在我面临一个不同的错误:
    error:error in proxy com.atomikos.jms.atomikosjmsceception
    您可以添加一个源代码来说明如何使用jms吗?可能您忘记了通过调用UserTransaction.begin()来启动事务。根据[javax.jms.Session docs]()“……由于Java分布式事务是通过Java事务API(JTA)控制的,因此在此上下文中禁止使用会话的提交和回滚方法。”但是,该代码在另一个app server/jms提供程序下运行良好。Ad localTransactionMode:您只需通过配置localTransactionMode=“true”关闭ActiveMQ的两阶段提交协议。Atomikos不会将XA事务与ActiveMQ资源一起使用,并且在提交此资源时只会使用一阶段本地事务协议。如果您只有一个这样的资源,并且(!)Atomikos正确地实现了最后一个资源策略优化,允许一个非XA资源参与分布式事务,那么这可能还是可以的。Ad session.commit():事实上,如果资源参与JTA(XA),您就不能使用JMS session.commit()或JDBC connection.commit()由事务管理器控制的事务。在开始使用资源之前,使用UserTransaction.begin()启动JTA事务。包装连接工厂的Atomikos代理类(例如AtomikoConnectionFactoryBean)创建Atomikos包装的会话/连接,以自动将它们登记到当前JTA事务(绑定到线程上下文),当您调用UserTransaction.commit()时,Atomikos将全部提交。
    import javax.transaction.Transaction;
    import javax.transaction.TransactionManager;
    import javax.transaction.UserTransaction;
    ...
    
    Hashtable<String, String> hashTable = new Hashtable<String, String>();
    try {
        Context ctx = new InitialContext(hashTable);
        ctx = (Context) jndiContext.lookup("java:comp/env");
    
        TransactionManager transactionManager = (TransactionManager) ctx.lookup("TransactionManager");
    } catch (Exception e) {
        e.printStackTrace();
    }
    
    com.atomikos.jms.AtomikosJMSException: Error in proxy
    at com.atomikos.jms.AtomikosJMSException.throwAtomikosJMSException(AtomikosJMSException.java:54)
    at com.atomikos.jms.ConsumerProducerSupport.handleException(ConsumerProducerSupport.java:61)
    at com.atomikos.jms.AtomikosJmsMessageConsumerProxy.receive(AtomikosJmsMessageConsumerProxy.java:73)
    at com.atomikos.jms.AtomikosJmsMessageConsumerProxy.receive(AtomikosJmsMessageConsumerProxy.java:137)
    ...
    at java.lang.Thread.run(Thread.java:619)
    Caused by: com.atomikos.jms.AtomikosTransactionRequiredJMSException: The JMS session you are using requires a JTA transaction context for the calling thread and none was found.
    Please correct your code to do one of the following: 
    1. start a JTA transaction if you want your JMS operations to be subject to JTA commit/rollback, or
    2. increase the maxPoolSize of the AtomikosConnectionFactoryBean to avoid transaction timeout while waiting for a connection, or
    3. create a non-transacted session and do session acknowledgment yourself, or
    4. set localTransactionMode to true so connection-level commit/rollback are enabled.
        at com.atomikos.jms.AtomikosTransactionRequiredJMSException.throwAtomikosTransactionRequiredJMSException(AtomikosTransactionRequiredJMSException.java:38)
        at com.atomikos.jms.ConsumerProducerSupport.enlist(ConsumerProducerSupport.java:107)
        at com.atomikos.jms.AtomikosJmsMessageConsumerProxy.receive(AtomikosJmsMessageConsumerProxy.java:70)
        ... 5 more