Hi all,

I have written a patch to make Tomcat work with Tyrex 1.0.  Here's a
summary of the new classes/code and how it all works.  I apologize for
the length of this post, the explanation is necessary I feel...

New class org.apache.naming.factory.TyrexFactory:

Tyrex now has the idea of a TransactionDomain, which manages resources
and transactions and is configured through an XML config file.  In order
to instantiate a TransactionDomain instance, the class must know two
things: the location of the domain config file, and the name of the
domain to lookup in the file.  The way I've set it up, these two string
configuration parameters must be present in the java:comp/env
namespace.  The TyrexFactory is an abstract superclass that provides a
method to lookup these configuration parameters and create the
TransactionDomain.  The two subclasses of this abstract class are...

New/modified class: org.apache.naming.factory.TyrexTransactionFactory:

This factory simply uses the TransactionDomain to create a
javax.transaction.UserTransaction.

New class org.apache.naming.factory.TyrexResourceFactory:
(this replaces TyrexDataSourceFactory)

Tyrex now also has the idea of resources, of which now there are only
two "flavors" right now:  JDBC DataSources and JCA connectors.  Since
the configuration of these resources must be done in Tyrex's domain XML
config file, this factory simply returns the resource with the specified
name -- it is up to the user know what to do with the Object returned.

Here's an example of how Tyrex would be setup for a simple JDBC
datasource.  Let's say you have a domain-config.xml file, with a domain
named "my-domain", which has a resource named "my-db", which is a JDBC
datasource (see Tyrex docs for more info).  In the server.xml file, we
would need to specify two environment parameters:

<Environment name="tyrexDomainConfig" type="java.lang.String"
             value="domain-config.xml"/>
<Environment name="tyrexDomainName" type="java.lang.String"
             value="my-domain"/>

and a resource:

<Resource name="my-datasource" auth="Container"
          type="tyrex.resource.Resource"/>
<ResourceParams name="my-datasource">
  <parameter>
    <name>name</name>
    <value>my-db</value>
  </parameter>
</ResourceParams>

This would all need to go under a <Context> element (I made the two
config strings global environment elements, and created ResourceLinks
instead).

Now, the domain-config.xml file is placed where the classloader can use
getResource() to find it (so, WEB-INF/classes is a good place), and
everything should be ready to go.  You can now do:

InitialContext initCtx = new InitialContext();
DataSource ds = (DataSource) 
                 initCtx.lookup("java:comp/env/my-datasource");
Connection conn = ds.getConnection();
... etc

in your user-level code.  Tyrex is still the default factory for
UserTransaction, so lookups on java:comp/env/UserTransaction work.

There are a few caveats:

(1) This is kind of a pain, but it's the way Tyrex 1.0 works.  This way
provides a lot of flexibility, without too much extra hassle.  If these
changes are made, however, a HOWTO is probably needed.  I can put one
together.
(2) For this to work, Tomcat now needs to be able to load the Tyrex
classes, and any classes it uses.  This means the tyrex jar and all
other jars included in the Tyrex distribution need to go in common/lib
(that includes JTA, OTS-JTS, and Xerces).  Furthermore, Tyrex needs some
JARs that it doesn't include in its distribution: the Castor XML jar,
and the Log4J jar.  This is six jars that need to be in common/lib for
Tyrex to work.  This kind of stinks as well.

Obviously there are probably a few kinks that need to be worked out, but
I've tested what is attached and it seems to work pretty well.

I've attached a cvs diff, as well as the two new files that are needed. 
These two new classes both go in the org.apache.naming.factory package. 
(remember TyrexDataSourceFactory needs to be removed)

Feedback/suggestions on my code is appreciated.  I'd like to see Tyrex
1.0 integrated with Tomcat fairly soon, so I'm prepared to make whatever
changes I need to in order to get the patch committed.

Thanks,

David
? jakarta-tomcat-4.0/catalina/src/share/org/apache/naming/factory/TyrexFactory.java
? 
jakarta-tomcat-4.0/catalina/src/share/org/apache/naming/factory/TyrexResourceFactory.java
Index: jakarta-tomcat-4.0/catalina/src/share//org/apache/naming/factory/Constants.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-tomcat-4.0/catalina/src/share/org/apache/naming/factory/Constants.java,v
retrieving revision 1.5
diff -b -d -u -r1.5 Constants.java
--- jakarta-tomcat-4.0/catalina/src/share//org/apache/naming/factory/Constants.java    
 17 May 2002 17:39:27 -0000      1.5
+++ jakarta-tomcat-4.0/catalina/src/share//org/apache/naming/factory/Constants.java    
+ 21 Jun 2002 07:47:10 -0000
@@ -91,8 +91,8 @@
     public static final String DBCP_DATASOURCE_FACTORY = 
         "org.apache.commons.dbcp.BasicDataSourceFactory";
 
-    public static final String TYREX_DATASOURCE_FACTORY = 
-        Package + ".TyrexDataSourceFactory";
+    public static final String TYREX_RESOURCE_FACTORY =
+        Package + ".TyrexResourceFactory";
 
     public static final String TYREX_TRANSACTION_FACTORY = 
         Package + ".TyrexTransactionFactory";
@@ -100,5 +100,9 @@
     public static final String OBJECT_FACTORIES = "";
 
     public static final String FACTORY = "factory";
+
+    public static final String TYREX_DOMAIN_CONFIG = "tyrexDomainConfig";
+
+    public static final String TYREX_DOMAIN_NAME = "tyrexDomainName";
 
 }
Index: 
jakarta-tomcat-4.0/catalina/src/share//org/apache/naming/factory/ResourceFactory.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-tomcat-4.0/catalina/src/share/org/apache/naming/factory/ResourceFactory.java,v
retrieving revision 1.7
diff -b -d -u -r1.7 ResourceFactory.java
--- 
jakarta-tomcat-4.0/catalina/src/share//org/apache/naming/factory/ResourceFactory.java  
     24 Feb 2002 05:09:58 -0000      1.7
+++ 
+jakarta-tomcat-4.0/catalina/src/share//org/apache/naming/factory/ResourceFactory.java 
+      21 Jun 2002 07:47:11 -0000
@@ -170,6 +170,16 @@
                             .newInstance();
                     } catch(Throwable t) {
                     }
+                } else if (ref.getClassName().equals("tyrex.resource.Resource")) {
+                    String tyrexResourceFactoryClassName =
+                        System.getProperty("tyrex.resource.Resource.Factory",
+                                           Constants.TYREX_RESOURCE_FACTORY);
+                    try {
+                        factory = (ObjectFactory)
+                            Class.forName(tyrexResourceFactoryClassName)
+                            .newInstance();
+                    } catch(Throwable t) {
+                    }
                 }
             }
             if (factory != null) {
Index: 
jakarta-tomcat-4.0/catalina/src/share//org/apache/naming/factory/TyrexTransactionFactory.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-tomcat-4.0/catalina/src/share/org/apache/naming/factory/TyrexTransactionFactory.java,v
retrieving revision 1.3
diff -b -d -u -r1.3 TyrexTransactionFactory.java
--- 
jakarta-tomcat-4.0/catalina/src/share//org/apache/naming/factory/TyrexTransactionFactory.java
       22 Feb 2002 08:47:14 -0000      1.3
+++ 
+jakarta-tomcat-4.0/catalina/src/share//org/apache/naming/factory/TyrexTransactionFactory.java
+       21 Jun 2002 07:47:11 -0000
@@ -71,21 +71,23 @@
 import javax.naming.Reference;
 import javax.naming.RefAddr;
 import javax.naming.spi.ObjectFactory;
+import java.net.URL;
 import org.apache.naming.TransactionRef;
-import tyrex.tm.Tyrex;
-
+import tyrex.tm.TransactionDomain;
+import javax.transaction.UserTransaction;
 /**
  * Object factory for Tyrex User transactions.<br>
+ *
  * Tyrex is an open-source transaction manager, developed by Assaf Arkin and
  * exolab.org. See the <a href="http://tyrex.exolab.org/";>Tyrex homepage</a>
  * for more details about Tyrex and downloads.
  * 
+ * @author David Haraburda
  * @author Remy Maucherat
  * @version $Revision: 1.3 $ $Date: 2002/02/22 08:47:14 $
  */
 
-public class TyrexTransactionFactory
-    implements ObjectFactory {
+public class TyrexTransactionFactory extends TyrexFactory {
 
 
     // ----------------------------------------------------------- Constructors
@@ -104,9 +106,9 @@
 
 
     /**
-     * Crete a new User transaction instance.
+     * Create a UserTransaction.
      * 
-     * @param obj The reference object describing the DataSource
+     * @param obj The reference object
      */
     public Object getObjectInstance(Object obj, Name name, Context nameCtx,
                                     Hashtable environment)
@@ -114,13 +116,11 @@
         
         if (obj instanceof TransactionRef) {
             Reference ref = (Reference) obj;
-            if (ref.getClassName()
-                .equals("javax.transaction.UserTransaction")) {
                 
+            if (ref.getClassName().equals("javax.transaction.UserTransaction") )
+            {
                 try {
-                    
-                    return Tyrex.getUserTransaction();
-                    
+                    return getTransactionDomain().getUserTransaction();
                 } catch (Throwable t) {
                     log("Cannot create Transaction, Exception", t);
                     throw new NamingException
/*
 * $Header$
 * $Revision$
 * $Date$
 *
 * ====================================================================
 *
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written
 *    permission, please contact [EMAIL PROTECTED]
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * [Additional notices, if required by prior licensing conditions]
 *
 */


package org.apache.naming.factory;

import java.net.URL;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.naming.spi.ObjectFactory;
import tyrex.tm.TransactionDomain;
import tyrex.tm.DomainConfigurationException;
import tyrex.tm.RecoveryException;

/**
 * Abstract superclass of any factory that creates objects from Tyrex.<br>
 *
 * Subclasses can use getTransactionDomain() to handle the retrieval and
 * creation of the TransactionDomain.
 *
 * Tyrex is an open-source transaction manager, developed by Assaf Arkin and
 * exolab.org. See the <a href="http://tyrex.exolab.org/";>Tyrex homepage</a>
 * for more details about Tyrex and downloads.
 *
 * @author David Haraburda
 * @version $Revision$ $Date$
 */

public abstract class TyrexFactory implements ObjectFactory {

    // ----------------------------------------------------------- Constructors


    // -------------------------------------------------------------- Constants


    // ----------------------------------------------------- Instance Variables


    // ------------------------------------------------------ Protected Methods

    /**
     * Get (and if necessary, create) the active TransactionDomain
     *
     * This class checks to see if there is already a TransactionDomain
     * setup and instantiated.  If so, it is returned, otherwise one is
     * created and initialized using properties obtained from JNDI.
     *
     */

    protected TransactionDomain getTransactionDomain() throws NamingException {
        TransactionDomain domain = null;
        InitialContext initCtx = new InitialContext();
        String config = initCtx.lookup("java:comp/env/" +
            Constants.TYREX_DOMAIN_CONFIG).toString();
        String name = initCtx.lookup("java:comp/env/" +
            Constants.TYREX_DOMAIN_NAME).toString();
        if( config != null && name != null ) {
            try {  // Tyrex throws exceptions if required classes aren't found.
                domain = TransactionDomain.getDomain(name);
            } catch( Throwable t ) {
                log("Error loading Tyrex TransactionDomain", t);
                throw new NamingException
                    ("Exception loading TransactionDomain: " + t.getMessage() );
            }
            if( domain == null ||
                domain.getState() == TransactionDomain.TERMINATED)
            {
                URL configURL = Thread.currentThread().getContextClassLoader().
                    getResource( config );
                if( configURL == null ) throw new NamingException
                    ("Could not load Tyrex domain config file");
                try {
                    domain = TransactionDomain.
                        createDomain( configURL.toString() );
                } catch( DomainConfigurationException dce ) {
                    throw new NamingException("Could not create " +
                        "TransactionDomain: " + dce.getMessage() );
                }
            }

        } else {
            throw new NamingException("Specified config file or domain name " +
                "parameters are invalid.");
        }
        if( domain.getState() == TransactionDomain.READY ) {
            try {
                domain.recover();
            } catch( RecoveryException re ) {
                throw new NamingException("Could not activate " +
                    "TransactionDomain: " + re.getMessage() );
            }
        }

        return domain;
    }



    // -------------------------------------------------------- Private Methods


    private void log(String message) {
        System.out.print("TyrexFactory:  ");
        System.out.println(message);
    }


    private void log(String message, Throwable exception) {
        log(message);
        exception.printStackTrace(System.out);
    }


}
/*
 * $Header$
 * $Revision$
 * $Date$
 *
 * ====================================================================
 *
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written
 *    permission, please contact [EMAIL PROTECTED]
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * [Additional notices, if required by prior licensing conditions]
 *
 */


package org.apache.naming.factory;

import java.util.Hashtable;
import java.util.Iterator;
import javax.naming.Name;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.RefAddr;
import javax.naming.spi.ObjectFactory;
import java.net.URL;
import org.apache.naming.ResourceRef;
import tyrex.tm.TransactionDomain;
import tyrex.resource.Resources;
import tyrex.resource.ResourceConfig;

/**
 * Object factory for Tyrex Resources.<br>
 *
 * This class retrieves Tyrex resources that are configured in the
 * TransactionDomain.  The type of Resource returned is specified in
 * Tyrex's domain configuration file.
 *
 * Tyrex is an open-source transaction manager, developed by Assaf Arkin and
 * exolab.org. See the <a href="http://tyrex.exolab.org/";>Tyrex homepage</a>
 * for more details about Tyrex and downloads.
 *
 * @author David Haraburda
 * @version $Revision$ $Date$
 */

public class TyrexResourceFactory
    extends TyrexFactory {


    // ----------------------------------------------------------- Constructors


    // -------------------------------------------------------------- Constants

    public static final String RESOURCE_NAME = "name";
    public static final String DEFAULT_RESOURCE_NAME = "tomcat";

    // ----------------------------------------------------- Instance Variables


    // --------------------------------------------------------- Public Methods


    // -------------------------------------------------- ObjectFactory Methods


    /**
     * Create a new Resource instance.  The type of Resource is dependant
     * upon Tyrex's domain configuration.
     *
     * @param obj The reference object describing the Resource
     */
    public Object getObjectInstance(Object obj, Name name, Context nameCtx,
                                    Hashtable environment)
        throws NamingException {

        if (obj instanceof ResourceRef) {
            Reference ref = (Reference) obj;

            if (ref.getClassName().equals("tyrex.resource.Resource"))
            {
                try {
                    Resources resources = getTransactionDomain().getResources();
                    RefAddr nameAddr = ref.get(RESOURCE_NAME);
                    if( nameAddr != null )
                        return resources.getResource( nameAddr.
                            getContent().toString() ).getClientFactory();
                    else
                        return resources.getResource(DEFAULT_RESOURCE_NAME).
                            getClientFactory();

                } catch (Throwable t) {
                    log("Cannot create Tyrex Resource, Exception", t);
                    throw new NamingException
                        ("Exception creating Tyrex Resource: " + t.getMessage());
                }

            }

        }

        return null;

    }


    // -------------------------------------------------------- Private Methods


    private void log(String message) {
        System.out.print("TyrexResourceFactory:  ");
        System.out.println(message);
    }


    private void log(String message, Throwable exception) {
        log(message);
        exception.printStackTrace(System.out);
    }


}


--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to