Welcome to Atomikos
Edit | Attach | New | Raw | Delete | History | Print | Tools
You are here: Main » WikiUsers » SamanehTorkAbadi

Tomcat 7.0.27 Integration with Atomikos 3.7.1

Recently, I upgraded Tomcat to version 7.0.27 and Atomikos to version 3.7.1. I read this page: Tomcat7Integration35 but not all the mentioned changes were applicable for Tomcat 7.0.27.

Edit 'server.xml'

As it is mentioned in this page: 'Edit server.xml' five listeners should be added to this page. But there are two classes that don't exist in this version of Tomcat:
  <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
  <Listener className="org.apache.catalina.storeconfig.StoreConfigLifecycleListener"/>

So, by excluding these two listeners and applying all other changes mentioned in Tomcat7Integration35, this integration works. But I realized that the auto-publish does not work for my application and none of the JNDI resources defined in 'context.xml' were found. In order to solve this problem, I made a work around 'EnhancedTomcatAtomikosBeanFactory.java' to check and close if any 'AtomikosConnectionFactoryBean' and 'AbstractDataSourceBean' exists. (Source code is attached to this page: 'atomikos-integration-extension-3.7.1-patch.zip')

'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.AbstractDataSourceBean;
import com.atomikos.jdbc.AtomikosDataSourceBean;
import com.atomikos.jdbc.AtomikosSQLException;
import com.atomikos.jms.AtomikosConnectionFactoryBean;
import com.atomikos.util.IntraVmObjectRegistry;

public class EnhancedTomcatAtomikosBeanFactory implements ObjectFactory {

    public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?,?> environment) throws NamingException
    {
        if (obj instanceof ResourceRef) {
            try {

                Reference ref = (Reference) obj;
                findAndCloseUniqueResource(ref);

                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<RefAddr> en = ref.getAll();
        while (en.hasMoreElements()) {
            RefAddr ra = 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<RefAddr> en = ref.getAll();
        while (en.hasMoreElements()) {
            RefAddr ra = 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;
    }

    /**
     * Check and close if any AtomikosConnectionFactoryBean and AbstractDataSourceBean exists
     * @param ref
     */
    private void findAndCloseUniqueResource(Reference ref){
        Enumeration<RefAddr> all = ref.getAll();
        while(all.hasMoreElements()) {
            RefAddr refAddrElement = all.nextElement();
            if(refAddrElement.getType().equals("uniqueResourceName")){
                closeIfExist(refAddrElement.getContent().toString());
            }
        }
    }

    /**
     * Close the existing AtomikosConnectionFactoryBean and AbstractDataSourceBean.
     * @param aName 
     */
    private void closeIfExist(String aName){
        try {
            Object o = IntraVmObjectRegistry.getResource(aName);
            if (o != null) {
                try {
                    if(o instanceof AtomikosConnectionFactoryBean) {
                        AtomikosConnectionFactoryBean o1 = (AtomikosConnectionFactoryBean)o;
                        o1.close();
                    }
                    else if (o instanceof AbstractDataSourceBean){
                        AbstractDataSourceBean o1 = (AbstractDataSourceBean)o;
                        o1.close();
                    }
                }
                catch(Exception se) {
                    se.printStackTrace();
                }
                IntraVmObjectRegistry.removeResource(aName);
            }
        } catch (Exception e) {
        }
    }

}

Edit 'context.xml'

"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>

Copy patched - Atomikos Integration Extension library

Copy atomikos-integration-extension-3.7.1-20120529.jar into TOMCAT_HOME/lib folder.
Attach
else version 1 uploaded by SamanehTorkAbadi on 29 May 2012 - 09:37
 
zip version 1 uploaded by SamanehTorkAbadi on 29 May 2012 - 10:22
 
spacer
Copyright © 2014 Atomikos BVBA. Transaction Management for Extreme Transaction Processing and SOA Environments serving ISV, Commercial, OEM and Open Source Markets
Site map RSS ATOM