Tomcat 7.0.27 Integration with Atomikos 3.7.1_码农丁丁的博客-程序员资料

技术标签: JAVA  tomcat Atomikos  

http://www.atomikos.com/Documentation/Tomcat7Integration35

 

Update: Tomcat 7.0.27 Integration with Atomikos 3.7.1

Installation is quite simple and it envolves the following steps:

 

1- Copy "atomikos-integration-extension-3.7.1-20120529.jar" into TOMCAT_HOME/lib folder.

This jar file contains:

  • 'AtomikosLifecycleListener.java'
  • 'EnhancedTomcatAtomikosBeanFactory.java'
  • 'pom.xml'
  • 'patch-README.txt'

Jar file and source code are available and attached to this page: atomikos-integration-extension-3.7.1-20120529.jarand atomikos-integration-extension-3.7.1-patch.zip

 

2- Edit "server.xml"

According to the needs of your application, standard and additional listeners which are available in Tomcat 7.0.27should be added to 'TOMCAT_HOME/conf/server.xml' file. Then right after the last one, add this listener:

<Listener className="com.atomikos.tomcat.AtomikosLifecycleListener" />

 

3- Edit "context.xml"

Then edit the TOMCAT_HOME/conf/context.xml file. At the beginning of the file you should see this line:

<WatchedResource>WEB-INF/web.xml</WatchedResource>

Right after it, add that one:

<Transaction factory="com.atomikos.icatch.jta.UserTransactionFactory" />

"com.atomikos.tomcat.EnhancedTomcatAtomikosBeanFactory" should be set as factory for both JDBC and JMS connection factory resources. Below, you can see an example of 'context.xml':

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

<!-- The contents of this file will be loaded for each web application -->
<Context>

    <!-- Default set of monitored resources -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>

  <!-- Atomikos Support for the Tomcat server - register Atomikos as java:comp/UserTransaction -->
  <Transaction factory="com.atomikos.icatch.jta.UserTransactionFactory" />
  <!-- Also register Atomikos TransactionManager as java:comp/env/TransactionManager -->
  <Resource name="TransactionManager"
            auth="Container"
            type="com.atomikos.icatch.jta.UserTransactionManager"
            factory="org.apache.naming.factory.BeanFactory" />

  <!-- Spring LoadTimeWeaver Support for the Tomcat server. -->
  <Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"
          useSystemClassLoaderAsParent="false"/>

  <Resource name="jdbc/MyDb"
            auth="Container"
            type="com.atomikos.jdbc.AtomikosDataSourceBean"
            factory="com.atomikos.tomcat.EnhancedTomcatAtomikosBeanFactory"
            uniqueResourceName="MyDb_Resource"
            maxPoolSize="8"
            xaDataSourceClassName="org.apache.derby.jdbc.ClientXADataSource"
            xaProperties.databaseName="MyDb"           
            xaProperties.connectionAttributes="serverName=localhost;portNumber=1527;user=USER;password=PASSWORD;create=true"/>

  <Resource name="jms/ConnectionFactory"
            auth="Container"
            type="com.atomikos.jms.AtomikosConnectionFactoryBean"
            factory="com.atomikos.tomcat.EnhancedTomcatAtomikosBeanFactory"
            uniqueResourceName="ConnectionFactory_Resource"
            xaConnectionFactoryClassName="org.apache.activemq.ActiveMQXAConnectionFactory"
            xaProperties.brokerURL="tcp://localhost:61616?daemon=true"/>

</Context>

 

Tomcat 7 Integration with Atomikos 3.5.2+

It is possible to fully integrate the Atomikos transaction manager into Tomcat. Doing it this way makes the transaction manager shared across all web applications exactly like with any full-blown J2EE server.

 

An apparently simpler way of configuring Tomcat6 with TransactionsEssentials is shown in this third-party blog entry:http://blog.vinodsingh.com/2009/12/jta-transactions-with-atomkios-in.html - we have not tested it though...

 

Important note

When the Atomikos transaction manager is installed globally in Tomcat, you now must also install your JDBC driver at the same global location (ie: into the TOMCAT_HOME/lib folder). If you dont do that, you will get a NoClassDefFoundErrors or a ClassNotFoundException or even a ClassCastException during your web application deployment.

This is not a limitation of Atomikos nor of Tomcat but of the J2EE class loading design that both Tomcat and Atomikos must follow.

 

Installation

Installation is quite simple, it just involves copying some JAR files, a property file and editing some Tomcat configuration files.

 

Atomikos Tomcat Lifecycle Class

The LifecycleListener has to be changed since release 3.5.2. The first class which calls UserTransactionManager.init() is the master for UserTransactionManager. It is not the first class which calls new UserTransactionManager(). Only the master closes UserTransactionManager with its close() method. Therefore UserTransactionManager.init() has to be called after the new operator.

Here is the revised source code:

 

Atomikos Lifecycle Listener.java

package com.atomikos.tomcat;

import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleListener;

import com.atomikos.icatch.jta.UserTransactionManager;

public class AtomikosLifecycleListener implements LifecycleListener
{

   private UserTransactionManager utm;

   public void lifecycleEvent(LifecycleEvent event)
   {
      try {
         if (Lifecycle.START_EVENT.equals(event.getType())) {
            if (utm == null) {
               utm = new UserTransactionManager();
            }
            utm.init();
         } else if (Lifecycle.AFTER_STOP_EVENT.equals(event.getType())) {
            if (utm != null) {
               utm.close();
            }
         }
      } catch (Exception e) {
      }
   }
}

 

Atomikos Tomcat BeanFactory Class

This JAR contains a single class file that is an enhanced version of Tomcat JNDI's Bean Factory. Here is its source code:

 

Bean Factory.java

package com.atomikos.tomcat;

import java.util.Enumeration;
import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;

import org.apache.naming.ResourceRef;
import org.apache.naming.factory.Constants;

import com.atomikos.beans.PropertyUtils;
import com.atomikos.jdbc.AtomikosDataSourceBean;

public class BeanFactory implements ObjectFactory
{

   public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws NamingException
   {
      if (obj instanceof ResourceRef) {
         try {
            Reference ref = (Reference) obj;
            String beanClassName = ref.getClassName();
            Class beanClass = null;
            ClassLoader tcl = Thread.currentThread().getContextClassLoader();
            if (tcl != null) {
               try {
                  beanClass = tcl.loadClass(beanClassName);
               } catch (ClassNotFoundException e) {
               }
            } else {
               try {
                  beanClass = Class.forName(beanClassName);
               } catch (ClassNotFoundException e) {
                  e.printStackTrace();
               }
            }
            if (beanClass == null) {
               throw new NamingException("Class not found: " + beanClassName);
            }
            if (!AtomikosDataSourceBean.class.isAssignableFrom(beanClass)) {
               throw new NamingException("Class is not a AtomikosDataSourceBean: " + beanClassName);
            }

            AtomikosDataSourceBean bean = (AtomikosDataSourceBean) beanClass.newInstance();

            int i = 0;
            Enumeration en = ref.getAll();
            while (en.hasMoreElements()) {
               RefAddr ra = (RefAddr) en.nextElement();
               String propName = ra.getType();

               if (propName.equals(Constants.FACTORY) || propName.equals("singleton") || propName.equals("description") || propName.equals("scope") || propName.equals("auth")) {
                  continue;
               }

               String value = (String) ra.getContent();

               PropertyUtils.setProperty(bean, propName, value);

               i++;
            }

            bean.init();
            return bean;

         } catch (Exception ex) {
            throw (NamingException) new NamingException("error creating AtomikosDataSourceBean").initCause(ex);
         }

      } else {
         return null;
      }
   }
}

 

Copying TransactionsEssentials libraries

 

  • Drop the following JARs from the Atomikos distribution into the TOMCAT_HOME/lib folder:
    • transactions.jar
    • transactions-api.jar
    • transactions-jta.jar
    • transactions-jdbc.jar
    • atomikos-util.jar.jar
    • jta.jar

You should also copy the transactions-hibernate3.jar and/or transactions-hibernate2.jar at the same location if you're planning to use Hibernate.

 

Copying Atomikos configuration file

 

  • Drop the following properties file into the TOMCAT_HOME/lib folder: jta.properties

 

Edit server.xml

Then edit the TOMCAT_HOME/conf/server.xml file. At the beginning of the file you should see these four lines:

 

  <Listener className="org.apache.catalina.core.AprLifecycleListener" />
  <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.storeconfig.StoreConfigLifecycleListener"/>

Right after the last one, add this fifth one:

 

 <Listener className="com.atomikos.tomcat.AtomikosLifecycleListener" />

 

Edit context.xml

Then edit the TOMCAT_HOME/conf/context.xml file. At the beginning of the file you should see this line:

 

 <WatchedResource>WEB-INF/web.xml</WatchedResource>

Right after it, add that one:

 

 <Transaction factory="com.atomikos.icatch.jta.UserTransactionFactory" />

 

Example application

Here is a sample application that demonstrates how you can run TransactionsEssentials in a web application after it has been globally installed.

It is a simple blueprint application that shows and updates the content of a single Derby database.

Download the sample application here: dbtest.war

To install it, simply copy the WAR file in Tomcat's webapps folder. You also need to install Derby's JDBC driver inTOMCAT_HOME/lib.

You can then access it via this URL: http://localhost:8080/dbtest/.

 

Notes

  • This demo uses an embedded Derby database. If it doesn't exist a new one is created in TOMCAT_HOME/work or else, the existing one is reused.
  • The transactions logs and debug logs are stored in TOMCAT_HOME/work.
  • You should get logs during Tomcat's startup and shutdown:
    • during startup: INFO: starting Atomikos Transaction Manager 3.3.0
    • during shutdown: INFO: shutting down Atomikos Transaction Manager

 

Using MySQL

The example uses Derby - however it can be configured with MySQL by changing the webapp context similar to this:

 

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/dbtest" docBase="dbtest.war"
reloadable="true" crossContext="true">
<!-- Resource configuration for JDBC datasource-->
<Resource
name="jdbc/myDB"
auth="Container"
type="com.atomikos.jdbc.AtomikosDataSourceBean"
factory="com.atomikos.tomcat.BeanFactory"
uniqueResourceName="jdbc/myDB"
xaDataSourceClassName="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"
xaProperties.databaseName="test"
xaProperties.serverName="localhost"
xaProperties.port="3306"
xaProperties.user="USER"
xaProperties.password="PASSWORD"
xaProperties.url="jdbc:mysql://localhost:3306/test"
/>
</Context>

Remember to change the parameter values to your specific environment...

 

Using WebSphere MQ

This example shows how to define pooled JMS Queue Connection Factories and Queues for WebSphere MQ. Note that the uniqueResourceName MUST contain the text MQSeries_XA_RMI.

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/dbtest" docBase="dbtest.war"
reloadable="true" crossContext="true">

<Resource 
name="jms/myQCF" 
auth="Container" 
type="com.atomikos.jms.AtomikosConnectionFactoryBean" 
factory="com.atomikos.tomcat.EnhancedTomcatAtomikosBeanFactory" 
uniqueResourceName="myQCF_MQSeries_XA_RMI" 
xaConnectionFactoryClassName="com.ibm.mq.jms.MQXAQueueConnectionFactory" 
xaProperties.queueManager="XXXX" 
xaProperties.hostName="hostname" 
xaProperties.port="1426" 
xaProperties.channel="XXXX" 
maxPoolSize="3" 
minPoolSize="1" />

<Resource name="jms/myQ" 
auth="Container" 
type="com.ibm.mq.jms.MQQueue" 
factory="com.ibm.mq.jms.MQQueueFactory" 
description="JMS Queue for reading messages" 
QU="MYQ.IN" 
CCSID="819" 
persistence="2" />         
</Context>

For this to work, you need an improved version of the Bean Factory described above, which can also handle JMS Connection Factory Beans:

!EnhancedTomcatAtomikosBeanFactory .java

package com.atomikos.tomcat;

import java.util.Enumeration;
import java.util.Hashtable;

import javax.jms.JMSException;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;

import org.apache.naming.ResourceRef;
import org.apache.naming.factory.Constants;

import com.atomikos.beans.PropertyException;
import com.atomikos.beans.PropertyUtils;
import com.atomikos.jdbc.AtomikosDataSourceBean;
import com.atomikos.jdbc.AtomikosSQLException;
import com.atomikos.jms.AtomikosConnectionFactoryBean;

/**
 * enhancement of com.atomikos.tomcat.BeanFactory (see http://www.atomikos.com/Documentation/Tomcat7Integration35)
 */
public class EnhancedTomcatAtomikosBeanFactory implements ObjectFactory
{

   public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws NamingException
   {
      if (obj instanceof ResourceRef) { //see http://fogbugz.atomikos.com/default.asp?community.6.2947.0 for a fix for OpenEJB!
         try {
            Reference ref = (Reference) obj;
            String beanClassName = ref.getClassName();
            Class beanClass = null;
            ClassLoader tcl = Thread.currentThread().getContextClassLoader();
            if (tcl != null) {
               try {
                  beanClass = tcl.loadClass(beanClassName);
               } catch (ClassNotFoundException e) {
               }
            } else {
               try {
                  beanClass = Class.forName(beanClassName);
               } catch (ClassNotFoundException e) {
                  e.printStackTrace();
               }
            }
            if (beanClass == null) {
               throw new NamingException("Class not found: " + beanClassName);
            }
            if (AtomikosDataSourceBean.class.isAssignableFrom(beanClass)) {
               return createDataSourceBean(ref, beanClass);
            } else if (AtomikosConnectionFactoryBean.class.isAssignableFrom(beanClass)) {
               return createConnectionFactoryBean(ref, beanClass);
            } else {
               throw new NamingException("Class is neither an AtomikosDataSourceBean nor an AtomikosConnectionFactoryBean: " + beanClassName);
            }

         } catch (Exception ex) {
            throw (NamingException) new NamingException("error creating AtomikosDataSourceBean").initCause(ex);
         }

      } else {
         return null;
      }
   }

   /**
    * create a DataSourceBean for a JMS datasource
    * 
    * @param ref
    * @param beanClass
    * @return
    * @throws InstantiationException
    * @throws IllegalAccessException
    * @throws PropertyException
    * @throws AtomikosSQLException
    * @throws JMSException
    */
   private Object createConnectionFactoryBean(Reference ref, Class beanClass) throws InstantiationException, IllegalAccessException, PropertyException, JMSException
   {
      AtomikosConnectionFactoryBean bean = (AtomikosConnectionFactoryBean) beanClass.newInstance();

      int i = 0;
      Enumeration en = ref.getAll();
      while (en.hasMoreElements()) {
         RefAddr ra = (RefAddr) en.nextElement();
         String propName = ra.getType();

         if (propName.equals(Constants.FACTORY) || propName.equals("singleton") || propName.equals("description") || propName.equals("scope") || propName.equals("auth")) {
            continue;
         }

         String value = (String) ra.getContent();

         PropertyUtils.setProperty(bean, propName, value);

         i++;
      }

      bean.init();
      return bean;
   }

   /**
    * create a DataSourceBean for a JDBC datasource
    * 
    * @param ref
    * @param beanClass
    * @return
    * @throws InstantiationException
    * @throws IllegalAccessException
    * @throws PropertyException
    * @throws AtomikosSQLException
    */
   private Object createDataSourceBean(Reference ref, Class beanClass) throws InstantiationException, IllegalAccessException, PropertyException, AtomikosSQLException
   {
      AtomikosDataSourceBean bean = (AtomikosDataSourceBean) beanClass.newInstance();

      int i = 0;
      Enumeration en = ref.getAll();
      while (en.hasMoreElements()) {
         RefAddr ra = (RefAddr) en.nextElement();
         String propName = ra.getType();

         if (propName.equals(Constants.FACTORY) || propName.equals("singleton") || propName.equals("description") || propName.equals("scope") || propName.equals("auth")) {
            continue;
         }

         String value = (String) ra.getContent();

         PropertyUtils.setProperty(bean, propName, value);

         i++;
      }

      bean.init();
      return bean;
   }
}

 

Copy Atomikos Integration Extension library

Copy atomikos-integration-extension.jar into TOMCAT_HOME/lib folder.

 

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xqdd/article/details/84479701

智能推荐

Python 读取文件夹(os.walk() )获取文件名以超链接方式(openpyxl)写入Excel的单元格某列。_python获取文件夹下文件的超链接_lucky_zbaby的博客-程序员资料

功能描述看代码的帮助信息。操作步骤。1.读取某个文件夹的所有文件夹下的文件名。2.通过openpyxl来操作Excel。3.将文件夹的文件名集合以超链接的方式写入Excel文件。# 推荐使用pandas,使用pandas方法可以不用在excel上点击import pandas as pdimport osimport openpyxl as opdef getfilename(filename): ''' 此函数完成获取文件夹名称 os.walk() 方法用于通过

LHL MOOC 计算机程序设计(C++)2020 期末考试 课程考试——编程题_mooc计算机程序设计(c++)期末考试编程题_Simple_questions的博客-程序员资料

1成绩统计(15分)题目内容:输入若干学生的成绩,统计各班的成绩的平均值,并按班级名称的机内码从小到大排序输出。学生成绩信息包括:班级,学号和成绩。班级名称是"000"'时表示成绩输入结束。班级名称不超过20字符,学号不超过10个字符,成绩为整数,平均成绩为双精度实数,保留三位小数。班级数不超过10个,总人数不超过100个。输入格式:若干行,每行信息包括班级,学号和成绩,用空格隔开,最后一行为:000 000 000输出格式:若干行,每行信息包括:班级和平均成绩,中间用一个空格隔开。行数由

pagehelper启动报错;使用pagehelper-spring-boot-starter报错_pagehelper使用后第一次连接报错_奇衡三丶的博客-程序员资料

错误信息:***************************APPLICATION FAILED TO START***************************Description:Field sqlSessionFactoryList in com.github.pagehelper.autoconfigure.PageHelperAutoConfiguration required a bean of type 'java.util.List' that could not

Python使用HTMLParser抓取网页内容_Wilson_Iceman的博客-程序员资料

昨天使用webdriver爬取了某电商网站的商品数据信息,webdriver其实是使用DOM格式来抓取网页数据的。但是使用DOM格式有一个问题,学过前端的同学都知道,如果使用DOM格式抓取数据,必须要等到DOM树形成之后才可以,也就是说DOM格式要完全完成之后才可以使用。但是对于某些特殊的情况,并不需要全部的DOM,可能只需要DOM中的一部分就可以了。在这种情况下webdriver就会显得效率有点

cocos2dx实战游戏开发之【别踩白块】------胜利与失败场景的实现_Lampard猿奋的博客-程序员资料

【别踩白块】游戏实战开发之胜利&amp;失败场景 大家好,我是Lampard------是一位从事cocos开发的游戏小白。 本人经验尚缺,如果各位大牛有更好的建议,欢迎在下方评论,谢谢!!! 今天要介绍的是游戏胜利&amp;失败场景的实现: (...

「拼得多」的地方,容不下一个天才黑客_平静愉悦的博客-程序员资料

朋友圈大牛蛙(王琦)原话:看到关于flanker和拼多多的文章,打开朋友圈想说两句,没想到朋友圈的草稿还停留在去年1024的一张照片,那刚好用上。第一,拼多多这样“无畏’逆’行”的企业能走多远?第二,面对同流合污去违法和因拒绝而损失亿元收益,有几人能做到flanker般“极有担当”?拼多多里我唯一认识的人是flanker,他2014年从阿里加入KEEN,是我的很帅的南阳小老乡,来了以后我才知道他妈妈我喊表姐,因为进步特别快,我在公司会上就直接叫他天才少年,他话不多,但我观察得出这..

随便推点

IDEA中Maven切换国内源_R15010198466的博客-程序员资料

国内访问Maven仓库非常慢,笔者今天忘记切换国内源更新Maven仓库竟然更新了一下午。如果改成国内的源,那么很快就更新完成了。在IDEA中打开“Settings”(快捷键++);在搜索框中输入“maven”,找到Maven设置菜单,点击进去,在红框所示路径新建“settings.xml”文件,并写入如下内容,勾选“”override,如下图所示:...

PVE系列教程(三)、安装黑威联通_pve 黑威联通_勤奋的凯尔森同学的博客-程序员资料

PVE系列教程(三)、安装黑威联通使用到的文件:https://pan.baidu.com/s/12Y_M8kvrUELrYRsSNaNZpw提取密码:xkrm一、创建虚拟机二、制作启动盘打开FileZilla或者WinSCP传输文件,连接PVE即可。文件上传完成后,输入chmod 777 img2km,回车。然后输入 ./img2km QNAPIG-BOOT.img [虚拟机id号],回车。我这里的虚拟机号为104。回到pve后台,点击创建的虚拟机-硬件,出现了一个未使

OpenSSL笔记_Soul_wwb的博客-程序员资料

OpenSSL 笔记文章目录OpenSSL 笔记对称加密(可以加解密文件)单向加密生成密钥对生成私钥生成公钥创建证书使用私钥签名X.509命令使用私钥与证书的存储格式Binary(DER)格式证书ASCII(PEM)格式证书Binary(DER)格式密钥ASCII(PEM)格式密钥PKCS#7格式证书PKCS#12(PFX)格式的密钥和证书TLS配置创建私有CA创建下级CA参考文章对称加密(可...

3.15_z1211t的博客-程序员资料

#include#include"./delay/delay.h"#include"./lcd1602/lcd1602.h"#include"./keyboard/keyboard.h"#define Ubuf_Max 150   //´¿Ú»º´æ³¤¶Èsbit Yellow_LED = P2^2; //LED1»ÆɫָʾµÆsbit Green

推荐文章

热门文章

相关标签