[jboss-svn-commits] JBL Code SVN: r17617 - in labs/jbosstm/trunk/ArjunaJTS: jtax/classes/com/arjuna/ats/internal/jta/transaction/jts and 4 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Tue Jan 8 06:28:07 EST 2008


Author: jhalliday
Date: 2008-01-08 06:28:07 -0500 (Tue, 08 Jan 2008)
New Revision: 17617

Added:
   labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jts/orbspecific/JTAInterposedSynchronizationImple.java
   labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/TransactionSynchronizationRegistryImple.java
Modified:
   labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jts/orbspecific/SynchronizationImple.java
   labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/TransactionImple.java
   labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/XATerminatorImple.java
   labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/orbspecific/coordinator/ArjunaTransactionImple.java
   labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/resources/SynchronizationRecord.java
   labs/jbosstm/trunk/ArjunaJTS/jts/idl/arjuna/ArjunaOTS.idl
Log:
Added JTA 1.1 support to the JTS (jtax), mainly consisting of copying the TransactionSynchronizationRegistry and associated changes over from the local JTA.See http://jira.jboss.com/jira/browse/JBTM-174


Added: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jts/orbspecific/JTAInterposedSynchronizationImple.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jts/orbspecific/JTAInterposedSynchronizationImple.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jts/orbspecific/JTAInterposedSynchronizationImple.java	2008-01-08 11:28:07 UTC (rev 17617)
@@ -0,0 +1,38 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a full listing
+ * of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License, v. 2.0.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License,
+ * v. 2.0 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ *
+ * (C) 2007,
+ * @author Red Hat Middleware LLC.
+ */
+package com.arjuna.ats.internal.jta.resources.jts.orbspecific;
+
+import com.arjuna.ArjunaOTS.JTAInterposedSynchronizationOperations;
+
+/**
+ * Implementation of the marker interface used to distinguish Synchronizations that
+ * should be interposed in the JTA 1.1 TransactionSynchronizationRegistry sense of the term.
+ */
+public class JTAInterposedSynchronizationImple extends SynchronizationImple implements JTAInterposedSynchronizationOperations {
+
+    public JTAInterposedSynchronizationImple(javax.transaction.Synchronization ptr) {
+        super(ptr);
+    }
+
+    protected org.omg.PortableServer.Servant getPOATie() {
+        return new com.arjuna.ArjunaOTS.JTAInterposedSynchronizationPOATie(this);
+    }
+}

Modified: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jts/orbspecific/SynchronizationImple.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jts/orbspecific/SynchronizationImple.java	2008-01-08 11:01:25 UTC (rev 17616)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jts/orbspecific/SynchronizationImple.java	2008-01-08 11:28:07 UTC (rev 17617)
@@ -1,20 +1,20 @@
 /*
  * JBoss, Home of Professional Open Source
  * Copyright 2006, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. 
- * See the copyright.txt in the distribution for a full listing 
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a full listing
  * of individual contributors.
  * This copyrighted material is made available to anyone wishing to use,
  * modify, copy, or redistribute it subject to the terms and conditions
  * of the GNU General Public License, v. 2.0.
- * This program is distributed in the hope that it will be useful, but WITHOUT A 
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  * PARTICULAR PURPOSE.  See the GNU General Public License for more details.
  * You should have received a copy of the GNU General Public License,
  * v. 2.0 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  * MA  02110-1301, USA.
- * 
+ *
  * (C) 2005-2006,
  * @author JBoss Inc.
  */
@@ -47,6 +47,7 @@
 import com.arjuna.ats.internal.jts.ORBManager;
 
 import com.arjuna.common.util.logging.*;
+import com.arjuna.ArjunaOTS.JTAInterposedSynchronizationHelper;
 
 import org.omg.CosTransactions.*;
 
@@ -79,9 +80,9 @@
  * @since JTS 1.2.4.
  */
 
-public class SynchronizationImple extends org.omg.CosTransactions.SynchronizationPOA 
+public class SynchronizationImple implements org.omg.CosTransactions.SynchronizationOperations
 {
-    
+
     public SynchronizationImple (javax.transaction.Synchronization ptr)
     {
 	_theSynch = ptr;
@@ -103,16 +104,18 @@
 
     public final org.omg.CosTransactions.Synchronization getSynchronization ()
     {
-	if (_theReference == null)
-	{
-	    ORBManager.getPOA().objectIsReady(this);
-	    
-	    _theReference = org.omg.CosTransactions.SynchronizationHelper.narrow(ORBManager.getPOA().corbaReference(this));
-	}
-	
-	return _theReference;
+        if (_theReference == null)
+        {
+            _thePOATie = getPOATie();
+
+            ORBManager.getPOA().objectIsReady(_thePOATie);
+
+            _theReference = org.omg.CosTransactions.SynchronizationHelper.narrow(ORBManager.getPOA().corbaReference(_thePOATie));
+        }
+
+        return _theReference;
     }
- 
+
     public void before_completion () throws org.omg.CORBA.SystemException
     {
 	if (jtaLogger.logger.isDebugEnabled())
@@ -153,14 +156,14 @@
 		_theSynch.afterCompletion(s);
 
 		if (_theReference != null)
-		    ORBManager.getPOA().shutdownObject(this);
+		    ORBManager.getPOA().shutdownObject(_thePOATie);
 	    }
 	    catch (Exception e)
 	    {
 		e.printStackTrace();
-		
+
 		if (_theReference != null)
-		    ORBManager.getPOA().shutdownObject(this);
+		    ORBManager.getPOA().shutdownObject(_thePOATie);
 
 		throw new UNKNOWN(); // should not cause any affect!
 	    }
@@ -169,7 +172,14 @@
 	    throw new UNKNOWN(); // should not cause any affect!
     }
 
+    // this is used to allow subclasses to override the Tie type provided.
+    // the Tie classes do not inherit from one another even if the business interfaces
+    // they correspond to do in the idl. Hence Servant is the only common parent.
+    protected org.omg.PortableServer.Servant getPOATie() {
+        return new org.omg.CosTransactions.SynchronizationPOATie(this);
+    }
+
     private javax.transaction.Synchronization       _theSynch;
     private org.omg.CosTransactions.Synchronization _theReference;
-
+    private org.omg.PortableServer.Servant _thePOATie;
 }

Modified: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/TransactionImple.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/TransactionImple.java	2008-01-08 11:01:25 UTC (rev 17616)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/TransactionImple.java	2008-01-08 11:28:07 UTC (rev 17617)
@@ -66,8 +66,7 @@
 
 import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
 
-import java.util.Hashtable;
-import java.util.Enumeration;
+import java.util.*;
 
 import javax.transaction.RollbackException;
 import java.lang.SecurityException;
@@ -445,12 +444,11 @@
 	 *          [com.arjuna.ats.internal.jta.transaction.jts.syncerror]
 	 *          Synchronizations are not allowed!
 	 */
-
 	public void registerSynchronization (javax.transaction.Synchronization sync)
 			throws javax.transaction.RollbackException,
 			java.lang.IllegalStateException, javax.transaction.SystemException
 	{
-		if (jtaLogger.logger.isDebugEnabled())
+        if (jtaLogger.logger.isDebugEnabled())
 		{
 			jtaLogger.logger.debug(DebugLevel.FUNCTIONS, VisibilityLevel.VIS_PUBLIC, com.arjuna.ats.jta.logging.FacilityCode.FAC_JTA, "TransactionImple.registerSynchronization");
 		}
@@ -460,13 +458,26 @@
 					"TransactionImple.registerSynchronization - "
 							+ jtaLogger.loggerI18N.getString("com.arjuna.ats.internal.jta.transaction.jts.nullparam"));
 
+        registerSynchronizationImple(new SynchronizationImple(sync));
+	}
+
+	// package-private method also for use by
+	// TransactionSynchronizationRegistryImple
+	/**
+	 * @message com.arjuna.ats.internal.jta.transaction.arjunacore.syncwhenaborted
+	 *          [com.arjuna.ats.internal.jta.transaction.arjunacore.syncwhenaborted]
+	 *          Can't register synchronization because the transaction is in
+	 *          aborted state
+	 */
+	void registerSynchronizationImple(SynchronizationImple synchronizationImple)
+			throws javax.transaction.RollbackException,
+			java.lang.IllegalStateException, javax.transaction.SystemException
+	{
 		if (_theTransaction != null)
 		{
 			try
 			{
-				SynchronizationImple s = new SynchronizationImple(sync);
-
-				_theTransaction.registerSynchronization(s.getSynchronization());
+                _theTransaction.registerSynchronization(synchronizationImple.getSynchronization());
 			}
 			catch (TRANSACTION_ROLLEDBACK e2)
 			{
@@ -497,7 +508,8 @@
 					jtaLogger.loggerI18N.getString("com.arjuna.ats.internal.jta.transaction.jts.inactivetx"));
 	}
 
-	public boolean enlistResource (XAResource xaRes) throws RollbackException,
+
+    public boolean enlistResource (XAResource xaRes) throws RollbackException,
 			IllegalStateException, javax.transaction.SystemException
 	{
 		return enlistResource(xaRes, null);
@@ -1222,15 +1234,41 @@
 		removeTransaction(this);
 	}
 
-	protected TransactionImple (AtomicTransaction tx)
+    // get a key-value pair from a transaction specific Map
+	public Object getTxLocalResource(Object key)
 	{
+		return _txLocalResources.get(key);
+	}
+
+	// store a key-value pair in the scope of the transaction.
+	public void putTxLocalResource(Object key, Object value)
+	{
+		_txLocalResources.put(key, value);
+	}
+
+
+    /*
+     * For JBossAS integration TransactionLocal implementation, we need to know if a tx has been
+     * resolved yet or not. We could use getStatus() and a case stmt, but since an instance is
+     * removed from _transactions on completion this is just as effective.
+     * @param tx
+     * @return
+     */
+    public boolean isAlive() {
+        return _transactions.contains(this);
+    }
+
+
+    protected TransactionImple (AtomicTransaction tx)
+	{
 		_theTransaction = tx;
 
 		if (tx != null)
 		{
 			_resources = new Hashtable();
 			_duplicateResources = new Hashtable();
-		}
+            _txLocalResources = Collections.synchronizedMap(new HashMap());
+        }
 		else
 		{
 			_resources = null;
@@ -1282,7 +1320,7 @@
 			jtaLogger.loggerI18N.warn("com.arjuna.ats.internal.jta.transaction.jts.syncproblem", ex);
 		}
 		_xaTransactionTimeoutEnabled = getXATransactionTimeoutEnabled() ;
-	}
+    }
 
 	protected void commitAndDisassociate ()
 			throws javax.transaction.RollbackException,
@@ -1761,6 +1799,7 @@
 	private Hashtable _duplicateResources;
 	private int _suspendCount;
 	private final boolean _xaTransactionTimeoutEnabled ;
+    private Map _txLocalResources;
 
         /**
          * Count of last resources seen in this transaction.

Added: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/TransactionSynchronizationRegistryImple.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/TransactionSynchronizationRegistryImple.java	                        (rev 0)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/TransactionSynchronizationRegistryImple.java	2008-01-08 11:28:07 UTC (rev 17617)
@@ -0,0 +1,254 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ *
+ * (C) 2006,
+ * @author JBoss Inc.
+ *
+ * $Id$
+ */
+package com.arjuna.ats.internal.jta.transaction.jts;
+
+import com.arjuna.ats.jta.logging.jtaLogger;
+import com.arjuna.ats.internal.jta.resources.jts.orbspecific.JTAInterposedSynchronizationImple;
+import com.arjuna.common.util.logging.DebugLevel;
+import com.arjuna.common.util.logging.VisibilityLevel;
+
+import javax.transaction.*;
+import java.io.Serializable;
+
+/**
+ * Implementation of the TransactionSynchronizationRegistry interface, in line with the JTA 1.1 specification.
+ *
+ * @author jonathan.halliday at jboss.com
+ */
+public class TransactionSynchronizationRegistryImple implements TransactionSynchronizationRegistry, Serializable {
+
+    // This Imple is stateless and just delegates the work down to the transaction manager.
+    // It's Serilizable so it can be shoved into the app server JNDI.
+
+    /*
+	 * http://java.sun.com/javaee/5/docs/api/javax/transaction/TransactionSynchronizationRegistry.html
+	 * http://jcp.org/aboutJava/communityprocess/maintenance/jsr907/907ChangeLog.html
+	 */
+
+	// Return an opaque object to represent the transaction bound to the current thread at the time this method is called.
+
+    /**
+	 * @message com.arjuna.ats.internal.jta.transaction.jts.systemexception
+	 * [com.arjuna.ats.internal.jta.transaction.jts.systemexception]
+	 * The transaction implementation threw a SystemException
+	 */
+	public Object getTransactionKey()
+	{
+		if (jtaLogger.logger.isDebugEnabled())
+		{
+			jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+					VisibilityLevel.VIS_PUBLIC,
+					com.arjuna.ats.jta.logging.FacilityCode.FAC_JTA,
+					"TransactionSynchronizationRegistryImple.getTransactionKey");
+		}
+
+        javax.transaction.TransactionManager tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
+		TransactionImple transactionImple = null;
+		try
+		{
+			transactionImple = (TransactionImple)tm.getTransaction();
+        }
+		catch (SystemException e)
+		{
+			throw new RuntimeException(jtaLogger.loggerI18N.getString("com.arjuna.ats.internal.jta.transaction.jts.systemexception"), e);
+		}
+
+		if (transactionImple == null) {
+			return null;
+		} else {
+			return transactionImple.get_uid();
+		}
+	}
+
+	// Add or replace an object in the Map of resources being managed for the transaction bound to the current thread at the time this method is called.
+	public void putResource(Object key, Object value)
+	{
+		if (jtaLogger.logger.isDebugEnabled())
+		{
+			jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+					VisibilityLevel.VIS_PUBLIC,
+					com.arjuna.ats.jta.logging.FacilityCode.FAC_JTA,
+					"TransactionSynchronizationRegistryImple.putResource");
+		}
+
+		if(key ==  null)
+		{
+			throw new NullPointerException();
+		}
+
+		TransactionImple transactionImple = getTransactionImple();
+		transactionImple.putTxLocalResource(key, value);
+	}
+
+	// Get an object from the Map of resources being managed for the transaction bound to the current thread at the time this method is called.
+	public Object getResource(Object key)
+	{
+		if (jtaLogger.logger.isDebugEnabled())
+		{
+			jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+					VisibilityLevel.VIS_PUBLIC,
+					com.arjuna.ats.jta.logging.FacilityCode.FAC_JTA,
+					"TransactionSynchronizationRegistryImple.getResource");
+		}
+
+		if(key ==  null)
+		{
+			throw new NullPointerException();
+		}
+
+		TransactionImple transactionImple = getTransactionImple();
+		return transactionImple.getTxLocalResource(key);
+	}
+
+	// Register a Synchronization instance with special ordering semantics.
+	/**
+	 * @message com.arjuna.ats.internal.jta.transaction.jts.syncrollbackexception
+	 * [ccom.arjuna.ats.internal.jta.transaction.jts.syncrollbackexception]
+	 * The transaction implementation threw a RollbackException
+	 */
+	public void registerInterposedSynchronization(Synchronization synchronization)
+	{
+		if (jtaLogger.logger.isDebugEnabled())
+		{
+			jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+					VisibilityLevel.VIS_PUBLIC,
+					com.arjuna.ats.jta.logging.FacilityCode.FAC_JTA,
+					"TransactionSynchronizationRegistryImple.registerInterposedSynchronization");
+		}
+
+		TransactionImple transactionImple = getTransactionImple();
+
+		try
+		{
+			transactionImple.registerSynchronizationImple(new JTAInterposedSynchronizationImple(synchronization));
+		}
+		catch (RollbackException e)
+		{
+			throw new RuntimeException(jtaLogger.loggerI18N.getString("com.arjuna.ats.internal.jta.transaction.jts.syncrollbackmexception"), e);
+		}
+		catch (SystemException e)
+		{
+			throw new RuntimeException(jtaLogger.loggerI18N.getString("com.arjuna.ats.internal.jta.transaction.jts.systemexception"), e);
+		}
+	}
+
+	// Return the status of the transaction bound to the current thread at the time this method is called.
+	public int getTransactionStatus()
+	{
+		if (jtaLogger.logger.isDebugEnabled())
+		{
+			jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+					VisibilityLevel.VIS_PUBLIC,
+					com.arjuna.ats.jta.logging.FacilityCode.FAC_JTA,
+					"TransactionSynchronizationRegistryImple.getTransactionStatus");
+		}
+
+		javax.transaction.TransactionManager tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
+		try
+		{
+			return tm.getStatus();
+		}
+		catch(SystemException e)
+		{
+			throw new RuntimeException(jtaLogger.loggerI18N.getString("com.arjuna.ats.internal.jta.transaction.jts.systemexception"), e);
+		}
+
+	}
+
+	// Set the rollbackOnly status of the transaction bound to the current thread at the time this method is called.
+	public void setRollbackOnly()
+	{
+		if (jtaLogger.logger.isDebugEnabled())
+		{
+			jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+					VisibilityLevel.VIS_PUBLIC,
+					com.arjuna.ats.jta.logging.FacilityCode.FAC_JTA,
+					"TransactionSynchronizationRegistryImple.setRollbackOnly");
+		}
+
+		javax.transaction.TransactionManager tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
+		try
+		{
+			Transaction transaction = tm.getTransaction();
+
+			if(transaction == null)
+			{
+				throw new IllegalStateException();
+			}
+
+			tm.setRollbackOnly();
+		}
+		catch (SystemException e)
+		{
+			throw new RuntimeException(jtaLogger.loggerI18N.getString("com.arjuna.ats.internal.jta.transaction.jts.systemexception"), e);
+		}
+	}
+
+	// Get the rollbackOnly status of the transaction bound to the current thread at the time this method is called.
+	public boolean getRollbackOnly()
+	{
+		if (jtaLogger.logger.isDebugEnabled())
+		{
+			jtaLogger.logger.debug(DebugLevel.FUNCTIONS,
+					VisibilityLevel.VIS_PUBLIC,
+					com.arjuna.ats.jta.logging.FacilityCode.FAC_JTA,
+					"TransactionSynchronizationRegistryImple.getRollbackOnly");
+		}
+
+		TransactionImple transactionImple = getTransactionImple();
+
+		if(transactionImple == null) {
+			throw new IllegalStateException();
+		}
+
+		try
+		{
+			return (transactionImple.getStatus() == Status.STATUS_MARKED_ROLLBACK);
+		}
+		catch (SystemException e)
+		{
+			throw new RuntimeException(jtaLogger.loggerI18N.getString("com.arjuna.ats.internal.jta.transaction.jts.systemexception"), e);
+		}
+	}
+
+	private TransactionImple getTransactionImple() throws IllegalStateException
+	{
+		javax.transaction.TransactionManager tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
+		TransactionImple transactionImple = null;
+		try
+		{
+			transactionImple = (TransactionImple)tm.getTransaction();
+		}
+		catch (SystemException e)
+		{
+			throw new RuntimeException(jtaLogger.loggerI18N.getString("com.arjuna.ats.internal.jta.transaction.jts.systemexception"), e);
+		}
+
+		if(transactionImple == null)
+		{
+			throw new IllegalStateException();
+		}
+
+		return transactionImple;
+	}
+}

Modified: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/XATerminatorImple.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/XATerminatorImple.java	2008-01-08 11:01:25 UTC (rev 17616)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/transaction/jts/jca/XATerminatorImple.java	2008-01-08 11:28:07 UTC (rev 17617)
@@ -1,20 +1,20 @@
 /*
  * JBoss, Home of Professional Open Source
  * Copyright 2006, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. 
- * See the copyright.txt in the distribution for a full listing 
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a full listing
  * of individual contributors.
  * This copyrighted material is made available to anyone wishing to use,
  * modify, copy, or redistribute it subject to the terms and conditions
  * of the GNU General Public License, v. 2.0.
- * This program is distributed in the hope that it will be useful, but WITHOUT A 
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  * PARTICULAR PURPOSE.  See the GNU General Public License for more details.
  * You should have received a copy of the GNU General Public License,
  * v. 2.0 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  * MA  02110-1301, USA.
- * 
+ *
  * (C) 2005-2006,
  * @author JBoss Inc.
  */
@@ -45,7 +45,6 @@
 import com.arjuna.ats.arjuna.coordinator.TxControl;
 import com.arjuna.ats.arjuna.objectstore.ObjectStore;
 import com.arjuna.ats.arjuna.state.InputObjectState;
-import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.TxImporter;
 import com.arjuna.ats.internal.jta.transaction.jts.subordinate.jca.TransactionImple;
 import com.arjuna.ats.internal.jta.transaction.jts.subordinate.jca.coordinator.ServerTransaction;
 import com.arjuna.ats.jta.utils.XAHelper;
@@ -53,7 +52,7 @@
 
 /**
  * The XATerminator implementation.
- * 
+ *
  * @author mcl
  *
  */
@@ -66,17 +65,17 @@
 		try
 		{
 			TransactionImple tx = TxImporter.getImportedTransaction(xid);
-			
+
 			if (tx == null)
 				throw new XAException(XAException.XAER_INVAL);
-			
+
 			if (tx.baseXid() != null)  // activate failed?
 			{
 				if (onePhase)
 					tx.doOnePhaseCommit();
 				else
 					tx.doCommit();
-				
+
 				TxImporter.removeImportedTransaction(xid);
 			}
 			else
@@ -85,7 +84,7 @@
 		catch (XAException ex)
 		{
 			// resource hasn't had a chance to recover yet
-			
+
 			if (ex.errorCode != XAException.XA_RETRY)
 			{
 				TxImporter.removeImportedTransaction(xid);
@@ -104,20 +103,20 @@
 		catch (SystemException ex)
 		{
 			TxImporter.removeImportedTransaction(xid);
-			
+
 			throw new XAException(XAException.XAER_RMERR);
 		}
 	}
-	
+
 	public void forget (Xid xid) throws XAException
 	{
 		try
 		{
 			TransactionImple tx = TxImporter.getImportedTransaction(xid);
-			
+
 			if (tx == null)
 				throw new XAException(XAException.XAER_INVAL);
-			
+
 			tx.doForget();
 		}
 		catch (Exception ex)
@@ -129,25 +128,25 @@
 			TxImporter.removeImportedTransaction(xid);
 		}
 	}
-	
+
 	public int prepare (Xid xid) throws XAException
 	{
 		try
 		{
 			TransactionImple tx = TxImporter.getImportedTransaction(xid);
-			
+
 			if (tx == null)
 				throw new XAException(XAException.XAER_INVAL);
-			
+
 			switch (tx.doPrepare())
 			{
 			case TwoPhaseOutcome.PREPARE_READONLY:
 				TxImporter.removeImportedTransaction(xid);
-				
-				return XAResource.XA_RDONLY;				
+
+				return XAResource.XA_RDONLY;
 			case TwoPhaseOutcome.PREPARE_NOTOK:
 				TxImporter.removeImportedTransaction(xid);  // TODO check if rollback is going to be called first
-				
+
 				throw new XAException(XAException.XA_RBROLLBACK);
 			case TwoPhaseOutcome.PREPARE_OK:
 				return XAResource.XA_OK;
@@ -164,7 +163,7 @@
 			throw ex;
 		}
 	}
-	
+
 	public Xid[] recover (int flag) throws XAException
 	{
 		/*
@@ -172,13 +171,13 @@
 		 * transactions. Our own crash recovery takes care of transactions imported
 		 * via CORBA, Web Services etc.
 		 */
-		
+
 		/*
 		 * Requires going through the objectstore for the states of imported
 		 * transactions. Our own crash recovery takes care of transactions imported
 		 * via CORBA, Web Services etc.
 		 */
-		
+
 		switch (flag)
 		{
 		case XAResource.TMSTARTRSCAN: // check the object store
@@ -199,23 +198,23 @@
 		default:
 			throw new XAException(XAException.XAER_PROTO);
 		}
-		
+
 		// if we are here, then check the object store
-		
+
 		Xid[] indoubt = null;
-		
+
 		try
 		{
 			ObjectStore objStore = new ObjectStore(TxControl.getActionStoreType());
 			InputObjectState states = new InputObjectState();
-			
+
 			// only look in the JCA section of the object store
 
 			if (objStore.allObjUids(ServerTransaction.getType(), states) && (states.notempty()))
 			{
 				Stack values = new Stack();
 				boolean finished = false;
-				
+
 				do
 				{
 					Uid uid = new Uid(Uid.nullUid());
@@ -239,7 +238,7 @@
 					}
 					else
 						finished = true;
-					
+
 				} while (!finished);
 
 				if (values.size() > 0)
@@ -247,7 +246,7 @@
 					int index = 0;
 
 					indoubt = new Xid[values.size()];
-								
+
 					while (!values.empty())
 					{
 						TransactionImple id = (TransactionImple) values.pop();
@@ -279,7 +278,7 @@
 			if (tx.baseXid() != null)
 			{
 				tx.doRollback();
-				
+
 				TxImporter.removeImportedTransaction(xid);
 			}
 			else
@@ -288,7 +287,7 @@
 		catch (XAException ex)
 		{
 			// resource hasn't had a chance to recover yet
-			
+
 			if (ex.errorCode != XAException.XA_RETRY)
 			{
 				TxImporter.removeImportedTransaction(xid);
@@ -307,11 +306,11 @@
 		catch (SystemException ex)
 		{
 			TxImporter.removeImportedTransaction(xid);
-			
+
 			throw new XAException(XAException.XAER_RMERR);
 		}
 	}
-	
+
 	private boolean _recoveryStarted = false;
-	
+
 }

Modified: labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/orbspecific/coordinator/ArjunaTransactionImple.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/orbspecific/coordinator/ArjunaTransactionImple.java	2008-01-08 11:01:25 UTC (rev 17616)
+++ labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/orbspecific/coordinator/ArjunaTransactionImple.java	2008-01-08 11:28:07 UTC (rev 17617)
@@ -1,20 +1,20 @@
 /*
  * JBoss, Home of Professional Open Source
  * Copyright 2006, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. 
- * See the copyright.txt in the distribution for a full listing 
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a full listing
  * of individual contributors.
  * This copyrighted material is made available to anyone wishing to use,
  * modify, copy, or redistribute it subject to the terms and conditions
  * of the GNU General Public License, v. 2.0.
- * This program is distributed in the hope that it will be useful, but WITHOUT A 
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  * PARTICULAR PURPOSE.  See the GNU General Public License for more details.
  * You should have received a copy of the GNU General Public License,
  * v. 2.0 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  * MA  02110-1301, USA.
- * 
+ *
  * (C) 2005-2006,
  * @author JBoss Inc.
  */
@@ -74,8 +74,9 @@
 import com.arjuna.ArjunaOTS.*;
 
 import org.omg.CORBA.CompletionStatus;
-import java.util.Enumeration;
 
+import java.util.*;
+
 import com.arjuna.ats.arjuna.exceptions.ObjectStoreException;
 import org.omg.CORBA.SystemException;
 import org.omg.CORBA.BAD_PARAM;
@@ -88,17 +89,17 @@
 
 /**
  * OTS implementation class.
- * 
+ *
  * Implements both the Coordinator & Terminator interfaces of OTS as a single
  * class.
- * 
+ *
  * Note, because Java does not support multiple inheritance we must make use of
  * the tie facility (uuuggghhhh!!!!)
- * 
+ *
  * @author Mark Little (mark at arjuna.com)
  * @version $Id: ArjunaTransactionImple.java 2342 2006-03-30 13:06:17Z  $
  * @since JTS 1.0.
- * 
+ *
  * @message com.arjuna.ats.internal.jts.orbspecific.coordinator.generror {0}
  *          caught exception: {1}
  * @message com.arjuna.ats.internal.jts.orbspecific.coordinator.rbofail {0}
@@ -170,14 +171,14 @@
 			 * Fully checked transactions only allow the thread which began the
 			 * transaction to terminate it. We get the id of the beginning
 			 * thread here.
-			 * 
+			 *
 			 * The spec. says nothing about crash recovery, so we better assume
 			 * it can always complete a transaction!
-			 * 
+			 *
 			 * If the creating thread dies before terminating the transaction
 			 * then we have a problem. Requires change to Thread class to abort
 			 * outstanding transactions in this case.
-			 * 
+			 *
 			 * Also, transaction timeouts cause abortion of the transaction by a
 			 * *different* thread! This must work even in the presence of
 			 * checked transactions!
@@ -322,7 +323,7 @@
 	 * example) then we do nothing - could throw TransactionRequired or
 	 * INVALID_TRANSACTION. However, if it was rolledback then we throw
 	 * TRANSACTION_ROLLEDBACK. Seems like an inconsistency.
-	 * 
+	 *
 	 * report_heuristics is ignored if we are a subtransaction.
 	 */
 
@@ -793,7 +794,7 @@
 	 * Resources are only registered with the current transaction, whereas
 	 * subtransaction aware resources are registered with their parents when the
 	 * current transaction ends.
-	 * 
+	 *
 	 * @message com.arjuna.ats.internal.jts.orbspecific.coordinator.rccreate
 	 *          Creation of RecoveryCoordinator for {0} threw: {1}
 	 * @message com.arjuna.ats.internal.jts.orbspecific.coordinator.rcnotcreated
@@ -1239,12 +1240,35 @@
 				synchronized (this)
 				{
 					if (_synchs == null)
-						_synchs = new HashList(10);
+                    {
+                        // Synchronizations should be stored (or at least iterated) in their natural order
+						_synchs = new TreeSet();
+                    }
 				}
 
-				SynchronizationRecord otsSync = new SynchronizationRecord(sync);
+                SynchronizationRecord otsSync;
 
-				if (!_synchs.add(otsSync))
+                if(sync._is_a(JTAInterposedSynchronizationHelper.id()))
+                {
+                    otsSync = new SynchronizationRecord(sync, true);
+                }
+                else
+                {
+                    otsSync = new SynchronizationRecord(sync);
+                }
+
+                // disallow addition of Synchronizations that would appear
+				// earlier in sequence than any that has already been called
+				// during the pre-commmit phase. This is required for
+				// JTA 1.1 Synchronization ordering behaviour
+				if(_currentRecord != null) {
+					Comparable c = (Comparable)otsSync;
+					if(c.compareTo(_currentRecord) != 1) {
+						throw new UNKNOWN(ExceptionCodes.ADD_FAILED, CompletionStatus.COMPLETED_NO);
+					}
+				}
+
+                if (!_synchs.add(otsSync))
 				{
 					otsSync = null;
 					throw new UNKNOWN(ExceptionCodes.ADD_FAILED,
@@ -1414,7 +1438,7 @@
 	}
 
 	protected void doBeforeCompletion () throws SystemException
-	{		
+	{
 		if (jtsLogger.logger.isDebugEnabled())
 		{
 			jtsLogger.logger.debug(DebugLevel.FUNCTIONS, VisibilityLevel.VIS_PROTECTED, com.arjuna.ats.jts.logging.FacilityCode.FAC_OTS, "ArjunaTransactionImple::doBeforeCompletion for "
@@ -1427,11 +1451,8 @@
 		/*
 		 * If we have a synchronization list then we must be top-level.
 		 */
-
-		if (_synchs != null)
+        if (_synchs != null)
 		{
-			HashListIterator iterator = new HashListIterator(_synchs);
-			SynchronizationRecord value = (SynchronizationRecord) iterator.iterate();
 			boolean doSuspend = false;
 			ControlWrapper cw = null;
 
@@ -1474,13 +1495,29 @@
 					 */
 				}
 
-				while (value != null)
-				{
-					Synchronization c = value.contents();
+               /*
+                * Since Synchronizations may add register other Synchronizations, we can't simply
+                * iterate the collection. Instead we work from an ordered copy, which we periodically
+                * check for freshness. The addSynchronization method uses _currentRecord to disallow
+                * adding records in the part of the array we have already traversed, thus all
+                * Synchronization will be called and the (jta only) rules on ordering of interposed
+                * Synchronization will be respected.
+                */
+               int lastIndexProcessed = -1;
+               SynchronizationRecord[] copiedSynchs = (SynchronizationRecord[])_synchs.toArray(new SynchronizationRecord[] {});
 
+               while( (lastIndexProcessed < _synchs.size()-1) && !problem) {
+
+                   // if new Synchronization have been registered, refresh our copy of the collection:
+                   if(copiedSynchs.length != _synchs.size()) {
+                       copiedSynchs = (SynchronizationRecord[])_synchs.toArray(new SynchronizationRecord[] {});
+                   }
+
+                   lastIndexProcessed = lastIndexProcessed+1;
+                   _currentRecord = copiedSynchs[lastIndexProcessed];
+
+					Synchronization c = _currentRecord.contents();
 					c.before_completion();
-
-					value = (SynchronizationRecord) iterator.iterate();
 				}
 			}
 			catch (SystemException e)
@@ -1583,8 +1620,6 @@
 
 		if (_synchs != null)
 		{
-			HashListIterator iterator = new HashListIterator(_synchs);
-			SynchronizationRecord value = (SynchronizationRecord) iterator.iterate();
 			ControlWrapper cw = null;
 			boolean doSuspend = false;
 
@@ -1624,8 +1659,22 @@
 			 * happened.
 			 */
 
-			while (value != null)
+			// afterCompletions should run in reverse order compared to beforeCompletions
+			Stack stack = new Stack();
+			Iterator iterator = _synchs.iterator();
+			while(iterator.hasNext()) {
+				stack.push(iterator.next());
+			}
+
+			iterator = stack.iterator();
+
+			/*
+			 * Regardless of failures, we must tell all synchronizations what
+			 * happened.
+			 */
+			while(!stack.isEmpty())
 			{
+				SynchronizationRecord value = (SynchronizationRecord)stack.pop();
 				Synchronization c = value.contents();
 
 				try
@@ -1651,8 +1700,6 @@
 					if (exp == null)
 						exp = e;
 				}
-
-				value = (SynchronizationRecord) iterator.iterate();
 			}
 
 			if (doSuspend)
@@ -1825,7 +1872,7 @@
 		 * If the resource is an ArjunaOTS.OTSAbstractRecord or an
 		 * ArjunaOTS.ArjunaSubtranAwareResource then we can do better record
 		 * manipulation, and proper nested actions.
-		 * 
+		 *
 		 * Based on the type of resource we create the right abstract record to
 		 * handle it, rather than a single abstract record which switches
 		 * protocols internally.
@@ -1922,14 +1969,14 @@
 
 	/*
 	 * The caller should delete the context.
-	 * 
+	 *
 	 * The propagation context is specified on a per client thread basis.
 	 * Therefore, at the server side we must maintain a hierarchy for each
 	 * thread. However, the server cannot simply tear down this hierarchy
 	 * whenever it receives a completely new one from the same thread, since the
 	 * OTS lets a thread suspend/resume contexts at will. Potential for memory
 	 * leaks in C++ version, but not Java!!
-	 * 
+	 *
 	 * Currently we assume that the hierarchy will be JBoss transactions so we
 	 * can get the parents of transactions. If it is not then we could simply
 	 * just call get_txcontext on the control!
@@ -2279,9 +2326,10 @@
 
 	private BasicAction rootAction;
 
-	private HashList _synchs;
+	private SortedSet _synchs;
+    private SynchronizationRecord _currentRecord; // the most recently processed Synchronization.
 
-	static int _ipType = Arjuna.XID();
+    static int _ipType = Arjuna.XID();
 
 	static boolean _subtran = true;
 

Modified: labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/resources/SynchronizationRecord.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/resources/SynchronizationRecord.java	2008-01-08 11:01:25 UTC (rev 17616)
+++ labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/resources/SynchronizationRecord.java	2008-01-08 11:28:07 UTC (rev 17617)
@@ -1,20 +1,20 @@
 /*
  * JBoss, Home of Professional Open Source
  * Copyright 2006, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. 
- * See the copyright.txt in the distribution for a full listing 
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a full listing
  * of individual contributors.
  * This copyrighted material is made available to anyone wishing to use,
  * modify, copy, or redistribute it subject to the terms and conditions
  * of the GNU General Public License, v. 2.0.
- * This program is distributed in the hope that it will be useful, but WITHOUT A 
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  * PARTICULAR PURPOSE.  See the GNU General Public License for more details.
  * You should have received a copy of the GNU General Public License,
  * v. 2.0 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  * MA  02110-1301, USA.
- * 
+ *
  * (C) 2005-2006,
  * @author JBoss Inc.
  */
@@ -24,7 +24,7 @@
  * Arjuna Solutions Limited,
  * Newcastle upon Tyne,
  * Tyne and Wear,
- * UK.  
+ * UK.
  *
  * $Id: SynchronizationRecord.java 2342 2006-03-30 13:06:17Z  $
  */
@@ -50,9 +50,9 @@
  * @since JTS 1.0.
  */
 
-public class SynchronizationRecord implements ListElement
+public class SynchronizationRecord implements ListElement, Comparable
 {
-    
+
     public SynchronizationRecord (Synchronization ptr)
     {
 	if (jtsLogger.logger.isDebugEnabled())
@@ -63,8 +63,14 @@
 
 	_ptr = ptr;
 	_uid = new Uid();
+    _isJTAInterposed = false;
     }
 
+    public SynchronizationRecord (Synchronization ptr, boolean isJTAInterposed) {
+        this(ptr);
+        _isJTAInterposed = isJTAInterposed;
+	}
+
     public void finalize ()
     {
 	if (jtsLogger.logger.isDebugEnabled())
@@ -93,7 +99,41 @@
 	return _uid;
     }
 
+    /*
+     * SyncronizationsImples are ordered first according to the isJTAInterposed property and then by Uid.
+     * Interposed synchronizations must come after non-interposed ones  (see
+     * TransactionSynchronizationRegistry)  The ordering within the interposed/non-interposed categories
+     * is arbitrary but must be defined for correct functioning of the sort. Just don't rely on it in
+     * application level code.
+     *
+     * Note that interposition here is in the JTA TSR interface sense, not CORBA TS.
+     *
+     * @param object
+     * @return
+     */
+    public int compareTo(Object object)
+    {
+        SynchronizationRecord other = (SynchronizationRecord)object;
+
+        if(this._isJTAInterposed && (!other._isJTAInterposed))
+        {
+            return 1;
+        }
+        else if((!this._isJTAInterposed) && other._isJTAInterposed)
+        {
+            return -1;
+        }
+        else if(this._uid.equals(other._uid))
+        {
+            return 0;
+        }
+        else
+        {
+            return this._uid.lessThan(other._uid) ? -1 : 1;
+        }
+    }
+
     private Uid             _uid;
     private Synchronization _ptr;
-
+    private boolean _isJTAInterposed;
 }

Modified: labs/jbosstm/trunk/ArjunaJTS/jts/idl/arjuna/ArjunaOTS.idl
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jts/idl/arjuna/ArjunaOTS.idl	2008-01-08 11:01:25 UTC (rev 17616)
+++ labs/jbosstm/trunk/ArjunaJTS/jts/idl/arjuna/ArjunaOTS.idl	2008-01-08 11:28:07 UTC (rev 17617)
@@ -1,20 +1,20 @@
 /*
  * JBoss, Home of Professional Open Source
  * Copyright 2006, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. 
- * See the copyright.txt in the distribution for a full listing 
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a full listing
  * of individual contributors.
  * This copyrighted material is made available to anyone wishing to use,
  * modify, copy, or redistribute it subject to the terms and conditions
  * of the GNU General Public License, v. 2.0.
- * This program is distributed in the hope that it will be useful, but WITHOUT A 
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  * PARTICULAR PURPOSE.  See the GNU General Public License for more details.
  * You should have received a copy of the GNU General Public License,
  * v. 2.0 along with this distribution; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  * MA  02110-1301, USA.
- * 
+ *
  * (C) 2005-2006,
  * @author JBoss Inc.
  */
@@ -63,7 +63,7 @@
 	long timeout;
 	long numberOfThreads;
     };
-    
+
     typedef sequence<CosTransactions::otid_t> txIds;
 
     // Some useful exceptions
@@ -133,7 +133,7 @@
 	boolean propagateOnCommit ();
 
 	boolean saveRecord ();
-    
+
 	void merge (in OTSAbstractRecord record);
 	void alter (in OTSAbstractRecord record);
 
@@ -142,6 +142,12 @@
 	boolean shouldMerge (in OTSAbstractRecord record);
 	boolean shouldReplace (in OTSAbstractRecord record);
     };
+
+    // for JTA 1.1 TransactionSynchronizationRegistry support, a marker interface
+    // for Interposed (in the JTA rather than CORBA sense) Synchronizations
+    interface JTAInterposedSynchronization : CosTransactions::Synchronization
+    {
+    };
 };
 
 #endif




More information about the jboss-svn-commits mailing list