[jboss-svn-commits] JBL Code SVN: r36775 - in labs/jbosstm/trunk: ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common and 37 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Thu Mar 3 09:38:00 EST 2011


Author: jhalliday
Date: 2011-03-03 09:37:59 -0500 (Thu, 03 Mar 2011)
New Revision: 36775

Modified:
   labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/CoreEnvironmentBean.java
   labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/CoreEnvironmentBeanMBean.java
   labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/RecoveryEnvironmentBean.java
   labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/RecoveryEnvironmentBeanMBean.java
   labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/logging/arjunaI18NLogger.java
   labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/logging/arjunaI18NLoggerImpl.java
   labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/recovery/TransactionStatusManager.java
   labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/utils/Utility.java
   labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/common/ClassloadingUtility.java
   labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/objectstore/jdbc/JDBCActionStore.java
   labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/objectstore/jdbc/JDBCStore.java
   labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/objectstore/jdbc/JDBCStoreEnvironmentBean.java
   labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/ExpiredEntryMonitor.java
   labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/PeriodicRecovery.java
   labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/RecActivatorLoader.java
   labs/jbosstm/trunk/ArjunaCore/docs/ArjunaCore_Development_Guide/en-US/Appendix_Class_Definitions.xml
   labs/jbosstm/trunk/ArjunaCore/docs/ArjunaCore_Development_Guide/en-US/Appendix_Object_Store_Implementations.xml
   labs/jbosstm/trunk/ArjunaCore/docs/ArjunaCore_Development_Guide/en-US/extras/EnvironmentBeans.xml
   labs/jbosstm/trunk/ArjunaCore/docs/ArjunaCore_Installation_And_Administration_Guide/en-US/Failure_Recovery_Administration.xml
   labs/jbosstm/trunk/ArjunaCore/docs/ArjunaCore_Installation_And_Administration_Guide/en-US/extras/default_recovery_extension_settings.xml
   labs/jbosstm/trunk/ArjunaCore/docs/ArjunaCore_Installation_And_Administration_Guide/en-US/extras/expiry_scanner_properties.xml
   labs/jbosstm/trunk/ArjunaCore/jbossts-properties-arjunacore.xml
   labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Installation_And_Administration_Guide/en-US/Failure_Recovery_Administration.xml
   labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Installation_And_Administration_Guide/en-US/extras/default_recovery_extension_settings.xml
   labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Installation_And_Administration_Guide/en-US/extras/expiry_scanner_properties.xml
   labs/jbosstm/trunk/ArjunaJTA/jbossts-properties-arjunajta.xml
   labs/jbosstm/trunk/ArjunaJTA/jdbc/classes/com/arjuna/ats/internal/jdbc/DirectRecoverableConnection.java
   labs/jbosstm/trunk/ArjunaJTA/jdbc/classes/com/arjuna/ats/internal/jdbc/drivers/modifiers/ModifierFactory.java
   labs/jbosstm/trunk/ArjunaJTA/jdbc/classes/com/arjuna/ats/jdbc/logging/jdbcI18NLogger.java
   labs/jbosstm/trunk/ArjunaJTA/jdbc/classes/com/arjuna/ats/jdbc/logging/jdbcI18NLoggerImpl.java
   labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore/XARecoveryModule.java
   labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/arjunacore/XAOnePhaseResource.java
   labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/arjunacore/XAResourceRecord.java
   labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/common/JTAEnvironmentBean.java
   labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/logging/jtaI18NLogger.java
   labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/logging/jtaI18NLoggerImpl.java
   labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Development_Guide/en-US/Failure_Recovery.xml
   labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Development_Guide/en-US/extras/ExpiryScanner-properties.xml
   labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Development_Guide/en-US/extras/RecoveryManager-properties.xml
   labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Development_Guide/en-US/extras/default-RecoveryExtension-settings.xml
   labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Installation_And_Administration_Guide/en-US/Failure_Recovery_Administration.xml
   labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Installation_And_Administration_Guide/en-US/extras/default_recovery_extension_settings.xml
   labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Installation_And_Administration_Guide/en-US/extras/expiry_scanner_properties.xml
   labs/jbosstm/trunk/ArjunaJTS/jbossts-properties-arjunajts.xml
   labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/recovery/jts/XARecoveryModule.java
   labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jts/orbspecific/XAResourceRecord.java
   labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/orbspecific/recovery/RecoveryEnablement.java
   labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/recovery/RecoveryInit.java
   labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/jts/logging/jtsI18NLogger.java
   labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/jts/logging/jtsI18NLoggerImpl.java
   labs/jbosstm/trunk/ArjunaJTS/orbportability/build.xml
   labs/jbosstm/trunk/ArjunaJTS/orbportability/classes/com/arjuna/orbportability/common/OrbPortabilityEnvironmentBean.java
   labs/jbosstm/trunk/ArjunaJTS/orbportability/classes/com/arjuna/orbportability/common/OrbPortabilityEnvironmentBeanMBean.java
   labs/jbosstm/trunk/ArjunaJTS/orbportability/classes/com/arjuna/orbportability/event/EventManager.java
   labs/jbosstm/trunk/ArjunaJTS/orbportability/classes/com/arjuna/orbportability/internal/utils/InitLoader.java
   labs/jbosstm/trunk/ArjunaJTS/orbportability/classes/com/arjuna/orbportability/logging/orbportabilityI18NLogger.java
   labs/jbosstm/trunk/atsintegration/transaction-jboss-beans.xml
   labs/jbosstm/trunk/atsintegration/transaction-jboss-beans.xml.jts
   labs/jbosstm/trunk/qa/tests/src/org/jboss/jbossts/qa/Utils/EmptyObjectStore.java
Log:
Classloading changes. JBTM-828


Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/CoreEnvironmentBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/CoreEnvironmentBean.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/CoreEnvironmentBean.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -20,10 +20,12 @@
  */
 package com.arjuna.ats.arjuna.common;
 
+import com.arjuna.ats.internal.arjuna.common.ClassloadingUtility;
 import com.arjuna.common.internal.util.propertyservice.PropertyPrefix;
 import com.arjuna.common.internal.util.propertyservice.FullPropertyName;
 import com.arjuna.ats.arjuna.utils.Utility;
 import com.arjuna.common.util.ConfigurationInfo;
+import com.arjuna.ats.arjuna.utils.Process;
 
 import java.io.File;
 
@@ -45,8 +47,11 @@
     private volatile int socketProcessIdPort = 0;
     @FullPropertyName(name = "com.arjuna.ats.internal.arjuna.utils.SocketProcessIdMaxPorts")
     private volatile int socketProcessIdMaxPorts = 1;
+
     @FullPropertyName(name = "com.arjuna.ats.internal.arjuna.utils.processImplementation")
-    private volatile String processImplementation = Utility.defaultProcessId;
+    private volatile String processImplementationClassName = Utility.defaultProcessId;
+    private volatile Process processImplementation = null;
+
     @FullPropertyName(name = "com.arjuna.ats.internal.arjuna.utils.pid")
     private volatile int pid = -1;
 
@@ -155,24 +160,80 @@
      * Default: "com.arjuna.ats.internal.arjuna.utils.SocketProcessId"
      * Equivalent deprecated property: com.arjuna.ats.internal.arjuna.utils.processImplementation
      *
-     * @return the name of a class implemeting Process.
+     * @return the name of a class implementing Process.
      */
-    public String getProcessImplementation()
+    public String getProcessImplementationClassName()
     {
-        return processImplementation;
+        return processImplementationClassName;
     }
 
     /**
      * Sets the class name of the Process implementation to use.
      *
-     * @param processImplementation the name of a class implementing Process.
+     * @param processImplementationClassName the name of a class implementing Process.
      */
-    public void setProcessImplementation(String processImplementation)
+    public void setProcessImplementationClassName(String processImplementationClassName)
     {
-        this.processImplementation = processImplementation;
+        synchronized(this) {
+            if(processImplementationClassName == null)
+            {
+                this.processImplementation = null;
+            }
+            else if(!processImplementationClassName.equals(this.processImplementationClassName))
+            {
+                this.processImplementation = null;
+            }
+            this.processImplementationClassName = processImplementationClassName;
+        }
     }
 
     /**
+     * Returns an instance of a class implementing com.arjuna.ats.arjuna.utils.Process.
+     *
+     * If there is no pre-instantiated instance set and classloading or instantiation fails,
+     * this method will log an appropriate warning and return null, not throw an exception.
+     *
+     * @return a Process implementation instance, or null.
+     */
+    public Process getProcessImplementation()
+    {
+        if(processImplementation == null && processImplementationClassName != null)
+        {
+            synchronized(this) {
+                if(processImplementation == null && processImplementationClassName != null) {
+                    processImplementation = ClassloadingUtility.loadAndInstantiateClass(Process.class, processImplementationClassName, null);
+                }
+            }
+        }
+
+        return processImplementation;
+    }
+
+    /**
+     * Sets the instance of com.arjuna.ats.arjuna.utils.Process
+     *
+     * @param instance an Object that implements Process, or null.
+     */
+    public void setProcessImplementation(Process instance)
+    {
+        synchronized(this)
+        {
+            Process oldInstance = this.processImplementation;
+            processImplementation = instance;
+
+            if(instance == null)
+            {
+                this.processImplementationClassName = null;
+            }
+            else if(instance != oldInstance)
+            {
+                String name = ClassloadingUtility.getNameForClass(instance);
+                this.processImplementationClassName = name;
+            }
+        }
+    }
+
+    /**
      * Returns the process id to use if ManualProcessId is selected. Should be uniq across all instances on the same host.
      *
      * Default: -1 (invalid, must be changed if used)

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/CoreEnvironmentBeanMBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/CoreEnvironmentBeanMBean.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/CoreEnvironmentBeanMBean.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -35,7 +35,7 @@
 
     int getSocketProcessIdMaxPorts();
 
-    String getProcessImplementation();
+    String getProcessImplementationClassName();
 
     int getPid();
 

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/RecoveryEnvironmentBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/RecoveryEnvironmentBean.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/RecoveryEnvironmentBean.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -20,6 +20,10 @@
  */
 package com.arjuna.ats.arjuna.common;
 
+import com.arjuna.ats.arjuna.recovery.ExpiryScanner;
+import com.arjuna.ats.arjuna.recovery.RecoveryActivator;
+import com.arjuna.ats.arjuna.recovery.RecoveryModule;
+import com.arjuna.ats.internal.arjuna.common.ClassloadingUtility;
 import com.arjuna.common.internal.util.propertyservice.PropertyPrefix;
 import com.arjuna.common.internal.util.propertyservice.FullPropertyName;
 import com.arjuna.common.internal.util.propertyservice.ConcatenationPrefix;
@@ -50,13 +54,16 @@
     private volatile int transactionStatusManagerExpiryTime = 12; // hours
 
     @ConcatenationPrefix(prefix = "com.arjuna.ats.arjuna.recovery.expiryScanner")
-    private volatile List<String> expiryScanners = new ArrayList<String>();
+    private volatile List<String> expiryScannerClassNames = new ArrayList<String>();
+    private volatile List<ExpiryScanner> expiryScanners = null;
 
     @ConcatenationPrefix(prefix = "com.arjuna.ats.arjuna.recovery.recoveryExtension")
-    private volatile List<String> recoveryExtensions = new ArrayList<String>();
+    private volatile List<String> recoveryModuleClassNames = new ArrayList<String>();
+    private volatile List<RecoveryModule> recoveryModules = null;
 
     @ConcatenationPrefix(prefix = "com.arjuna.ats.arjuna.recovery.recoveryActivator")
-    private volatile List<String> recoveryActivators = new ArrayList<String>();
+    private volatile List<String> recoveryActivatorClassNames = new ArrayList<String>();
+    private volatile List<RecoveryActivator> recoveryActivators = null;
 
     @FullPropertyName(name = "com.arjuna.ats.internal.arjuna.recovery.listener.timeoutsocket")
     private volatile boolean timeoutSocket = false;
@@ -155,7 +162,7 @@
     }
 
     /**
-     * Returns the hostname on which the recovery listener shoud bind.
+     * Returns the hostname on which the recovery listener should bind.
      *
      * Default: "localhost"
      * Equivalent deprecated property: com.arjuna.ats.arjuna.recovery.recoveryAddress
@@ -301,9 +308,12 @@
      *
      * @return a list of ExpiryScanner implementation class names.
      */
-    public List<String> getExpiryScanners()
+    public List<String> getExpiryScannerClassNames()
     {
-        return new ArrayList<String>(expiryScanners);
+        synchronized(this)
+        {
+            return new ArrayList<String>(expiryScannerClassNames);
+        }
     }
 
     /**
@@ -311,18 +321,72 @@
      * List elements should be names of classes that implement ExpiryScanner.
      * The provided list will be copied, not retained.
      *
-     * @param expiryScanners a list of ExpiryScanner implementation class names.
+     * @param expiryScannerClassNames a list of ExpiryScanner implementation class names.
      */
-    public void setExpiryScanners(List<String> expiryScanners)
+    public void setExpiryScannerClassNames(List<String> expiryScannerClassNames)
     {
-        if(expiryScanners == null) {
-            this.expiryScanners = new ArrayList<String>();
-        } else {
-            this.expiryScanners = new ArrayList<String>(expiryScanners);
+        synchronized(this)
+        {
+            if(expiryScannerClassNames == null)
+            {
+                this.expiryScanners = new ArrayList<ExpiryScanner>();
+                this.expiryScannerClassNames = new ArrayList<String>();
+            }
+            else if(!expiryScannerClassNames.equals(this.expiryScannerClassNames))
+            {
+                this.expiryScanners = null;
+                this.expiryScannerClassNames = new ArrayList<String>(expiryScannerClassNames);
+            }
         }
     }
 
     /**
+     * Returns the set of ExpiryScanner instances.
+     * The returned list is a copy. May return an empty list, will not return null.
+     *
+     * If there is no pre-instantiated instance set and classloading or instantiation of one or more
+     * elements fails, this method will log an appropriate warning and return a non-null set with
+     * fewer elements.
+     *
+     * @return the set of ExpiryScanner instances.
+     */
+    public List<ExpiryScanner> getExpiryScanners()
+    {
+        synchronized(this)
+        {
+            if(expiryScanners == null) {
+                List<ExpiryScanner> instances = ClassloadingUtility.loadAndInstantiateClasses(ExpiryScanner.class, expiryScannerClassNames);
+                expiryScanners = instances;
+            }
+            return new ArrayList<ExpiryScanner>(expiryScanners);
+        }
+    }
+
+    /**
+     * Sets the instances of ExpiryScanner.
+     * The provided list will be copied, not retained.
+     *
+     * @param expiryScanners the set of ExpiryScanner instances.
+     */
+    public void setExpiryScanners(List<ExpiryScanner> expiryScanners)
+    {
+        synchronized(this)
+        {
+            if(expiryScanners == null)
+            {
+                this.expiryScanners = new ArrayList<ExpiryScanner>();
+                this.expiryScannerClassNames = new ArrayList<String>();
+            }
+            else
+            {
+                this.expiryScanners = new ArrayList<ExpiryScanner>(expiryScanners);
+                List<String> names = ClassloadingUtility.getNamesForClasses(this.expiryScanners);
+                this.expiryScannerClassNames = names;
+            }
+        }
+    }
+
+    /**
      * Returns a list of names of classes that implement RecoveryModule.
      * The returned list is a copy. May return an empty list, will not return null.
      *
@@ -331,9 +395,11 @@
      *
      * @return a list of RecoveryModule implementation class names.
      */
-    public List<String> getRecoveryExtensions()
+    public List<String> getRecoveryModuleClassNames()
     {
-        return new ArrayList<String>(recoveryExtensions);
+        synchronized(this) {
+            return new ArrayList<String>(recoveryModuleClassNames);
+        }
     }
 
     /**
@@ -341,18 +407,73 @@
      * List elements should be names of classes that implement RecoveryModule.
      * The provided list will be copied, not retained.
      *
-     * @param recoveryExtensions a list of RecoveryModule implementation class names.
+     * @param recoveryModuleClassNames a list of RecoveryModule implementation class names.
      */
-    public void setRecoveryExtensions(List<String> recoveryExtensions)
+    public void setRecoveryModuleClassNames(List<String> recoveryModuleClassNames)
     {
-        if(recoveryExtensions == null) {
-            this.recoveryExtensions = new ArrayList<String>();
-        } else {
-            this.recoveryExtensions = new ArrayList<String>(recoveryExtensions);
+        synchronized(this)
+        {
+            if(recoveryModuleClassNames == null)
+            {
+                this.recoveryModules = new ArrayList<RecoveryModule>();
+                this.recoveryModuleClassNames = new ArrayList<String>();
+            }
+            else if(!recoveryModuleClassNames.equals(this.recoveryModuleClassNames))
+            {
+                this.recoveryModules = null;
+                this.recoveryModuleClassNames = new ArrayList<String>(recoveryModuleClassNames);
+            }
         }
     }
 
     /**
+     * Returns the set of RecoveryModule instances.
+     * The returned list is a copy. May return an empty list, will not return null.
+     *
+     * If there is no pre-instantiated instance set and classloading or instantiation of one or more
+     * elements fails, this method will log an appropriate warning and return a non-null set with
+     * fewer elements. 
+     *
+     * @return the set of RecoveryModule instances.
+     */
+    public List<RecoveryModule> getRecoveryModules()
+    {
+        synchronized(this)
+        {
+            if(recoveryModules == null) {
+                List<RecoveryModule> instances = ClassloadingUtility.loadAndInstantiateClassesWithInit(RecoveryModule.class, recoveryModuleClassNames);
+                recoveryModules = instances;
+            }
+            return new ArrayList<RecoveryModule>(recoveryModules);
+        }
+    }
+
+    /**
+     * Sets the instances of RecoveryModule.
+     * The provided list will be copied, not retained.
+     *
+     * @param recoveryModules the set of RecoveryModule instances.
+     */
+    public void setRecoveryModules(List<RecoveryModule> recoveryModules)
+    {
+        synchronized(this)
+        {
+            if(recoveryModules == null)
+            {
+                this.recoveryModules = new ArrayList<RecoveryModule>();
+                this.recoveryModuleClassNames = new ArrayList<String>();
+            }
+            else
+            {
+                this.recoveryModules = new ArrayList<RecoveryModule>(recoveryModules);
+                List<String> names = ClassloadingUtility.getNamesForClasses(this.recoveryModules);
+                this.recoveryModuleClassNames = names;
+            }
+        }
+    }
+    
+
+    /**
      * Returns a list of names of classes that implement RecoveryActivator.
      * The returned list is a copy. May return an empty list, will not return null.
      *
@@ -361,9 +482,11 @@
      *
      * @return a list of RecoveryActivator implementation class names.
      */
-    public List<String> getRecoveryActivators()
+    public List<String> getRecoveryActivatorClassNames()
     {
-        return new ArrayList<String>(recoveryActivators);
+        synchronized(this) {
+            return new ArrayList<String>(recoveryActivatorClassNames);
+        }
     }
 
     /**
@@ -371,18 +494,72 @@
      * List elements should be names of classes that implement RecoveryActivator.
      * The provided list will be copied, not retained.
      *
-     * @param recoveryActivators a list of RecoveryActivator implementation class names.
+     * @param recoveryActivatorClassNames a list of RecoveryActivator implementation class names.
      */
-    public void setRecoveryActivators(List<String> recoveryActivators)
+    public void setRecoveryActivatorClassNames(List<String> recoveryActivatorClassNames)
     {
-        if(recoveryActivators == null) {
-            this.recoveryActivators = new ArrayList<String>();
-        } else {
-           this.recoveryActivators = new ArrayList<String>(recoveryActivators);
+        synchronized(this)
+        {
+            if(recoveryActivatorClassNames == null)
+            {
+                this.recoveryActivators = new ArrayList<RecoveryActivator>();
+                this.recoveryActivatorClassNames = new ArrayList<String>();
+            }
+            else if(!recoveryActivatorClassNames.equals(this.recoveryActivatorClassNames))
+            {
+                this.recoveryActivators = null;
+                this.recoveryActivatorClassNames = new ArrayList<String>(recoveryActivatorClassNames);
+            }
         }
     }
 
     /**
+     * Returns the set of RecoveryActivator instances.
+     * The returned list is a copy. May return an empty list, will not return null.
+     *
+     * If there is no pre-instantiated instance set and classloading or instantiation of one or more
+     * elements fails, this method will log an appropriate warning and return a non-null set with
+     * fewer elements.
+     *
+     * @return the set of RecoveryActivator instances.
+     */
+    public List<RecoveryActivator> getRecoveryActivators()
+    {
+        synchronized(this)
+        {
+            if(recoveryActivators == null) {
+                List<RecoveryActivator> instances = ClassloadingUtility.loadAndInstantiateClassesWithInit(RecoveryActivator.class, recoveryActivatorClassNames);
+                recoveryActivators = instances;
+            }
+            return new ArrayList<RecoveryActivator>(recoveryActivators);
+        }
+    }
+
+    /**
+     * Sets the instances of RecoveryActivator.
+     * The provided list will be copied, not retained.
+     *
+     * @param recoveryActivators the set of RecoveryActivator instances.
+     */
+    public void setRecoveryActivators(List<RecoveryActivator> recoveryActivators)
+    {
+        synchronized(this)
+        {
+            if(recoveryActivators == null)
+            {
+                this.recoveryActivators = new ArrayList<RecoveryActivator>();
+                this.recoveryActivatorClassNames = new ArrayList<String>();
+            }
+            else
+            {
+                this.recoveryActivators = new ArrayList<RecoveryActivator>(recoveryActivators);
+                List<String> names = ClassloadingUtility.getNamesForClasses(this.recoveryActivators);
+                this.recoveryActivatorClassNames = names;
+            }
+        }
+    }
+
+    /**
      * Returns true if SO_TIMEOUT should be set on Listener socket instances.
      *
      * Default: false

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/RecoveryEnvironmentBeanMBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/RecoveryEnvironmentBeanMBean.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/common/RecoveryEnvironmentBeanMBean.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -47,11 +47,11 @@
 
     int getTransactionStatusManagerExpiryTime();
 
-    List<String> getExpiryScanners();
+    List<String> getExpiryScannerClassNames();
 
-    List<String> getRecoveryExtensions();
+    List<String> getRecoveryModuleClassNames();
 
-    List<String> getRecoveryActivators();
+    List<String> getRecoveryActivatorClassNames();
 
     boolean isTimeoutSocket();
 }

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/logging/arjunaI18NLogger.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/logging/arjunaI18NLogger.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/logging/arjunaI18NLogger.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -708,17 +708,17 @@
 	@LogMessage(level = INFO)
 	public void info_recovery_TransactionStatusManager_3(String arg0, String arg1, String arg2);
 
-	@Message(id = 12171, value = "Class not found: {0}", format = MESSAGE_FORMAT)
+	@Message(id = 12171, value = "Failed to setup class for {0}", format = MESSAGE_FORMAT)
 	@LogMessage(level = WARN)
 	public void warn_recovery_TransactionStatusManager_4(String arg0);
 
-	@Message(id = 12172, value = "Failed to instantiate service class: {0}", format = MESSAGE_FORMAT)
-	@LogMessage(level = WARN)
-	public void warn_recovery_TransactionStatusManager_5(String arg0);
+//	@Message(id = 12172, value = "Failed to instantiate service class: {0}", format = MESSAGE_FORMAT)
+//	@LogMessage(level = WARN)
+//	public void warn_recovery_TransactionStatusManager_5(String arg0);
 
-	@Message(id = 12173, value = "Illegal access to service class: {0}", format = MESSAGE_FORMAT)
-	@LogMessage(level = WARN)
-	public void warn_recovery_TransactionStatusManager_6(String arg0);
+//	@Message(id = 12173, value = "Illegal access to service class: {0}", format = MESSAGE_FORMAT)
+//	@LogMessage(level = WARN)
+//	public void warn_recovery_TransactionStatusManager_6(String arg0);
 
 //	@Message(id = 12174, value = "Failed to create server socket on port: {0}", format = MESSAGE_FORMAT)
 //	@LogMessage(level = WARN)
@@ -837,9 +837,9 @@
 	@LogMessage(level = WARN)
 	public void warn_utils_FileLock_4(String arg0);
 
-	@Message(id = 12209, value = "Utility.getDefaultProcess - failed with", format = MESSAGE_FORMAT)
+	@Message(id = 12209, value = "Utility.getDefaultProcess failed", format = MESSAGE_FORMAT)
 	@LogMessage(level = WARN)
-	public void warn_utils_Utility_1(@Cause() Throwable arg0);
+	public void warn_utils_Utility_1();
 
 	@Message(id = 12210, value = "Unable to use InetAddress.getLocalHost() to resolve address.", format = MESSAGE_FORMAT)
 	@LogMessage(level = WARN)
@@ -1164,9 +1164,9 @@
 	@LogMessage(level = WARN)
 	public void warn_recovery_Connection_2();
 
-	@Message(id = 12294, value = "Loading expiry scanner: could not find class {0}", format = MESSAGE_FORMAT)
-	@LogMessage(level = WARN)
-	public void warn_recovery_ExpiredEntryMonitor_10(String arg0);
+//	@Message(id = 12294, value = "Loading expiry scanner: could not find class {0}", format = MESSAGE_FORMAT)
+//	@LogMessage(level = WARN)
+//	public void warn_recovery_ExpiredEntryMonitor_10(String arg0);
 
 //	@Message(id = 12295, value = "{0} has inappropriate value ({1})", format = MESSAGE_FORMAT)
 //	@LogMessage(level = WARN)
@@ -1180,13 +1180,13 @@
 	@LogMessage(level = INFO)
 	public void info_recovery_ExpiredEntryMonitor_5();
 
-	@Message(id = 12298, value = "Attempt to load expiry scanner with null class name!", format = MESSAGE_FORMAT)
-	@LogMessage(level = WARN)
-	public void warn_recovery_ExpiredEntryMonitor_7();
+//	@Message(id = 12298, value = "Attempt to load expiry scanner with null class name!", format = MESSAGE_FORMAT)
+//	@LogMessage(level = WARN)
+//	public void warn_recovery_ExpiredEntryMonitor_7();
 
-	@Message(id = 12299, value = "Expiry scanner {0} does not conform to ExpiryScanner interface", format = MESSAGE_FORMAT)
-	@LogMessage(level = WARN)
-	public void warn_recovery_ExpiredEntryMonitor_9(String arg0);
+//	@Message(id = 12299, value = "Expiry scanner {0} does not conform to ExpiryScanner interface", format = MESSAGE_FORMAT)
+//	@LogMessage(level = WARN)
+//	public void warn_recovery_ExpiredEntryMonitor_9(String arg0);
 
 //	@Message(id = 12300, value = "ExpiredTransactionScanner created, with expiry time of {0} seconds", format = MESSAGE_FORMAT)
 //	@LogMessage(level = WARN)
@@ -1212,9 +1212,9 @@
 //	@LogMessage(level = WARN)
 //	public void warn_recovery_ExpiredTransactionStatusManagerScanner_5(String arg0, String arg1);
 
-	@Message(id = 12306, value = "Attempt to load recovery module with null class name!", format = MESSAGE_FORMAT)
-	@LogMessage(level = WARN)
-	public void warn_recovery_PeriodicRecovery_1();
+//	@Message(id = 12306, value = "Attempt to load recovery module with null class name!", format = MESSAGE_FORMAT)
+//	@LogMessage(level = WARN)
+//	public void warn_recovery_PeriodicRecovery_1();
 
 //	@Message(id = 12307, value = "Ignoring request to scan because RecoveryManager state is: {0}", format = MESSAGE_FORMAT)
 //	@LogMessage(level = WARN)
@@ -1232,21 +1232,21 @@
 	@LogMessage(level = INFO)
 	public void info_recovery_PeriodicRecovery_13(String arg0, String arg1);
 
-	@Message(id = 12311, value = "Recovery module {0} does not conform to RecoveryModule interface", format = MESSAGE_FORMAT)
-	@LogMessage(level = WARN)
-	public void warn_recovery_PeriodicRecovery_2(String arg0);
+//	@Message(id = 12311, value = "Recovery module {0} does not conform to RecoveryModule interface", format = MESSAGE_FORMAT)
+//	@LogMessage(level = WARN)
+//	public void warn_recovery_PeriodicRecovery_2(String arg0);
 
-	@Message(id = 12312, value = "Loading recovery module", format = MESSAGE_FORMAT)
-	@LogMessage(level = WARN)
-	public void warn_recovery_PeriodicRecovery_3(@Cause() Throwable arg0);
+//	@Message(id = 12312, value = "Loading recovery module", format = MESSAGE_FORMAT)
+//	@LogMessage(level = WARN)
+//	public void warn_recovery_PeriodicRecovery_3(@Cause() Throwable arg0);
 
-	@Message(id = 12313, value = "Loading recovery module", format = MESSAGE_FORMAT)
-	@LogMessage(level = WARN)
-	public void warn_recovery_PeriodicRecovery_4(@Cause() Throwable arg0);
+//	@Message(id = 12313, value = "Loading recovery module", format = MESSAGE_FORMAT)
+//	@LogMessage(level = WARN)
+//	public void warn_recovery_PeriodicRecovery_4(@Cause() Throwable arg0);
 
-	@Message(id = 12314, value = "Loading recovery module: could not find class {0}", format = MESSAGE_FORMAT)
-	@LogMessage(level = WARN)
-	public void warn_recovery_PeriodicRecovery_5(String arg0);
+//	@Message(id = 12314, value = "Loading recovery module: could not find class {0}", format = MESSAGE_FORMAT)
+//	@LogMessage(level = WARN)
+//	public void warn_recovery_PeriodicRecovery_5(String arg0);
 
 //	@Message(id = 12315, value = "{0} has inappropriate value ( {1} )", format = MESSAGE_FORMAT)
 //	@LogMessage(level = WARN)
@@ -1418,9 +1418,9 @@
 	@Message(id = 12359, value = "SocketProcessId.getpid could not get unique port.", format = MESSAGE_FORMAT)
 	public String get_utils_SocketProcessId_2();
 
-    @Message(id = 12360, value = "Unable to instantiate ExpiryScanner", format = MESSAGE_FORMAT)
-    @LogMessage(level = WARN)
-    public void warn_recovery_ExpiredEntryMonitor_6(@Cause() Throwable arg0);
+//    @Message(id = 12360, value = "Unable to instantiate ExpiryScanner", format = MESSAGE_FORMAT)
+//    @LogMessage(level = WARN)
+//    public void warn_recovery_ExpiredEntryMonitor_6(@Cause() Throwable arg0);
 
     @Message(id = 12361, value = "Error constructing mbean", format = MESSAGE_FORMAT)
     @LogMessage(level = INFO)

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/logging/arjunaI18NLoggerImpl.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/logging/arjunaI18NLoggerImpl.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/logging/arjunaI18NLoggerImpl.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -644,17 +644,17 @@
 	}
 
 	public void warn_recovery_TransactionStatusManager_4(String arg0) {
-		logger.logv(WARN, "ARJUNA-12171 Class not found: {0}", arg0);
+		logger.logv(WARN, "ARJUNA-12171 Failed to setup class for: {0}", arg0);
 	}
 
-	public void warn_recovery_TransactionStatusManager_5(String arg0) {
-		logger.logv(WARN, "ARJUNA-12172 Failed to instantiate service class: {0}", arg0);
-	}
+//	public void warn_recovery_TransactionStatusManager_5(String arg0) {
+//		logger.logv(WARN, "ARJUNA-12172 Failed to instantiate service class: {0}", arg0);
+//	}
+//
+//	public void warn_recovery_TransactionStatusManager_6(String arg0) {
+//		logger.logv(WARN, "ARJUNA-12173 Illegal access to service class: {0}", arg0);
+//	}
 
-	public void warn_recovery_TransactionStatusManager_6(String arg0) {
-		logger.logv(WARN, "ARJUNA-12173 Illegal access to service class: {0}", arg0);
-	}
-
 	public String get_recovery_TransactionStatusManager_9() {
 		return "ARJUNA-12176 Could not get unique port.";
 	}
@@ -771,8 +771,8 @@
 		logger.logv(WARN, "ARJUNA-12208 An error occurred while creating file {0}", arg0);
 	}
 
-	public void warn_utils_Utility_1(Throwable arg0) {
-		logger.logv(WARN, arg0, "ARJUNA-12209 Utility.getDefaultProcess - failed with", (Object)null);
+	public void warn_utils_Utility_1() {
+		logger.logv(WARN, "ARJUNA-12209 Utility.getDefaultProcess failed", (Object)null);
 	}
 
 	public void warn_utils_Utility_2() {

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/recovery/TransactionStatusManager.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/recovery/TransactionStatusManager.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/recovery/TransactionStatusManager.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -36,6 +36,7 @@
 
 import com.arjuna.ats.arjuna.exceptions.FatalError;
 import com.arjuna.ats.arjuna.utils.Utility ;
+import com.arjuna.ats.internal.arjuna.common.ClassloadingUtility;
 import com.arjuna.ats.internal.arjuna.recovery.Listener ;
 import com.arjuna.ats.internal.arjuna.recovery.TransactionStatusManagerItem ;
 
@@ -119,35 +120,28 @@
     */
    private void start( String serviceName, String host, int port )
    {
-      try
-      {
-         Class serviceClass = Thread.currentThread().getContextClassLoader().loadClass( serviceName ) ;
+       try
+       {
+           Service service = ClassloadingUtility.loadAndInstantiateClass(Service.class, serviceName,  null);
+           if(service == null) {
+               tsLogger.i18NLogger.warn_recovery_TransactionStatusManager_4(serviceName);
+               return;
+           }
 
-         Service service = (Service) serviceClass.newInstance() ;
+           ServerSocket socketServer = getTsmServerSocket(host, port);
 
-         ServerSocket socketServer = getTsmServerSocket(host, port);
+           addService( service, socketServer ) ;
 
-         addService( service, socketServer ) ;
+           TransactionStatusManagerItem.createAndSave(socketServer.getInetAddress().getHostAddress(), socketServer.getLocalPort() ) ;
 
-         TransactionStatusManagerItem.createAndSave(socketServer.getInetAddress().getHostAddress(), socketServer.getLocalPort() ) ;
+           tsLogger.i18NLogger.info_recovery_TransactionStatusManager_3(Integer.toString(socketServer.getLocalPort()),
+                   socketServer.getInetAddress().getHostAddress(), serviceName);
+       }
+       catch ( IOException ex ) {
+           tsLogger.i18NLogger.warn_recovery_TransactionStatusManager_14(getListenerHostName(), Integer.toString(getListenerPort(-1)));
 
-         tsLogger.i18NLogger.info_recovery_TransactionStatusManager_3(Integer.toString(socketServer.getLocalPort()),
-                 socketServer.getInetAddress().getHostAddress(), serviceName);
-      }
-      catch ( ClassNotFoundException ex ) {
-          tsLogger.i18NLogger.warn_recovery_TransactionStatusManager_4(serviceName);
-      }
-      catch ( InstantiationException ex ) {
-          tsLogger.i18NLogger.warn_recovery_TransactionStatusManager_5(serviceName);
-      }
-      catch ( IllegalAccessException ex ) {
-          tsLogger.i18NLogger.warn_recovery_TransactionStatusManager_6(serviceName);
-      }
-      catch ( IOException ex ) {
-          tsLogger.i18NLogger.warn_recovery_TransactionStatusManager_14(getListenerHostName(), Integer.toString(getListenerPort(-1)));
-
-          throw new FatalError(tsLogger.i18NLogger.get_recovery_TransactionStatusManager_9(), ex);
-      }
+           throw new FatalError(tsLogger.i18NLogger.get_recovery_TransactionStatusManager_9(), ex);
+       }
    }
 
     public void shutdown()

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/utils/Utility.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/utils/Utility.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/utils/Utility.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -34,6 +34,7 @@
 import com.arjuna.ats.arjuna.logging.tsLogger;
 
 import com.arjuna.ats.arjuna.common.*;
+import com.arjuna.ats.internal.arjuna.common.ClassloadingUtility;
 
 import java.net.Inet6Address;
 import java.net.InetAddress;
@@ -324,20 +325,14 @@
         processHandle = p;
     }
 
-    @SuppressWarnings("unchecked")
     private static synchronized void initDefaultProcess ()
     {
         if(processHandle == null)
         {
-            try
-            {
-                Class c = Thread.currentThread().getContextClassLoader().loadClass( arjPropertyManager.getCoreEnvironmentBean().getProcessImplementation());
-
-                processHandle = (Process) c.newInstance();
+            processHandle = arjPropertyManager.getCoreEnvironmentBean().getProcessImplementation();
+            if(processHandle == null) {
+                tsLogger.i18NLogger.warn_utils_Utility_1();
             }
-            catch (final Exception e) {
-                tsLogger.i18NLogger.warn_utils_Utility_1(e);
-            }
         }
     }
 

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/common/ClassloadingUtility.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/common/ClassloadingUtility.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/common/ClassloadingUtility.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -121,46 +121,67 @@
         return instance;
     }
 
-    public static <T> List<T> loadAndInstantiateClassesWithInit(Class<T> iface, List<String> classNamesWithOptionalInitParams)
+    public static <T> List<T> loadAndInstantiateClasses(Class<T> iface, List<String> classNames)
     {
         List<T> instances = new ArrayList<T>();
 
-        for(String theClassAndParameter : classNamesWithOptionalInitParams)
-        {
-            // see if there is a string parameter
+        if(classNames != null) {
+            for(String className : classNames)
+            {
+                T instance = loadAndInstantiateClass(iface, className, null);
+                if(instance != null)
+                {
+                    instances.add(instance);
+                }
+            }
+        }
 
-            int breakPosition = theClassAndParameter.indexOf(BREAKCHARACTER);
+        return instances;
+    }
 
-            String theClass = null;
-            String theParameter = null;
 
-            if (breakPosition != -1)
+    public static <T> List<T> loadAndInstantiateClassesWithInit(Class<T> iface, List<String> classNamesWithOptionalInitParams)
+    {
+        List<T> instances = new ArrayList<T>();
+
+        if(classNamesWithOptionalInitParams != null) {
+            for(String theClassAndParameter : classNamesWithOptionalInitParams)
             {
-                theClass = theClassAndParameter.substring(0, breakPosition);
-                theParameter = theClassAndParameter.substring(breakPosition + 1);
-            }
-            else
-            {
-                theClass = theClassAndParameter;
-            }
+                // see if there is a string parameter
 
-            T instance = loadAndInstantiateClass(iface, theClass, null);
+                int breakPosition = theClassAndParameter.indexOf(BREAKCHARACTER);
 
+                String theClass = null;
+                String theParameter = null;
 
-            if (theClass != null && theParameter != null)
-            {
-                try {
-                    Method method = instance.getClass().getMethod("initialise", new Class[] {String.class}); // yup, UK English spelling
-                    method.invoke(instance, theParameter);
-                } catch(Exception e) {
-                    tsLogger.i18NLogger.warn_common_ClassloadingUtility_6(theClassAndParameter, e);
-                    continue;
+                if (breakPosition != -1)
+                {
+                    theClass = theClassAndParameter.substring(0, breakPosition);
+                    theParameter = theClassAndParameter.substring(breakPosition + 1);
                 }
-            }
+                else
+                {
+                    theClass = theClassAndParameter;
+                }
 
-            if(instance != null)
-            {
-                instances.add(instance);
+                T instance = loadAndInstantiateClass(iface, theClass, null);
+
+
+                if (theClass != null && theParameter != null)
+                {
+                    try {
+                        Method method = instance.getClass().getMethod("initialise", new Class[] {String.class}); // yup, UK English spelling
+                        method.invoke(instance, theParameter);
+                    } catch(Exception e) {
+                        tsLogger.i18NLogger.warn_common_ClassloadingUtility_6(theClassAndParameter, e);
+                        continue;
+                    }
+                }
+
+                if(instance != null)
+                {
+                    instances.add(instance);
+                }
             }
         }
 

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/objectstore/jdbc/JDBCActionStore.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/objectstore/jdbc/JDBCActionStore.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/objectstore/jdbc/JDBCActionStore.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -149,7 +149,7 @@
     {
         super(jdbcStoreEnvironmentBean);
 
-        _txClassName = jdbcStoreEnvironmentBean.getJdbcTxDbAccess();
+        _txClassName = jdbcStoreEnvironmentBean.getJdbcTxDbAccessClassName();
     }
 
     protected String getAccessClassName()

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/objectstore/jdbc/JDBCStore.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/objectstore/jdbc/JDBCStore.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/objectstore/jdbc/JDBCStore.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -46,6 +46,7 @@
 
 import com.arjuna.ats.arjuna.exceptions.ObjectStoreException;
 import com.arjuna.ats.arjuna.exceptions.FatalError;
+import com.arjuna.ats.internal.arjuna.common.ClassloadingUtility;
 
 import java.io.IOException;
 
@@ -112,7 +113,7 @@
     public String getStoreName()
     {
         if (storeValid())
-            return getAccessClassName() + ":" + getTableName();
+            return getJDBCAccess().getClass().getName() + ":" + getTableName();
         else
             return "Invalid";
     }
@@ -285,13 +286,11 @@
 
     public synchronized void packInto(OutputBuffer buff) throws IOException
     {
-        buff.packString(getAccessClassName());
         buff.packString(getTableName());
     }
 
     public synchronized void unpackFrom(InputBuffer buff) throws IOException
     {
-        setAccessClassName(buff.unpackString());
         setTableName(buff.unpackString());
     }
 
@@ -337,48 +336,10 @@
     {
         this.jdbcStoreEnvironmentBean = jdbcStoreEnvironmentBean;
 
-         _jdbcAccessClassName = jdbcStoreEnvironmentBean.getJdbcUserDbAccess();
-
-        if(_jdbcAccessClassName == null) {
-            throw new ObjectStoreException(tsLogger.i18NLogger.get_objectstore_JDBCStore_5());
-        }
-
-        setTableName(_defaultTableName);
-
-        try
-        {
-            setupStore(_jdbcAccessClassName, getTableName());
-        }
-        catch (Exception e)
-        {
-            tsLogger.i18NLogger.fatal_objectstore_JDBCStore_1(getJDBCAccess().toString(), getTableName());
-            throw new ObjectStoreException(e);
-        }
-
-        _isValid = true;
+        initialise();
     }
 
     /**
-     * Get the JDBC access class name.
-     *
-     * @return The access class name.
-     */
-    protected String getAccessClassName()
-    {
-        return _jdbcAccessClassName;
-    }
-
-    /**
-     * Set the JDBC access class name.
-     *
-     * @param jdbcAccessClassName access class name.
-     */
-    protected void setAccessClassName(String jdbcAccessClassName)
-    {
-        _jdbcAccessClassName = jdbcAccessClassName;
-    }
-
-    /**
      * Get the JDBC default table name.
      *
      * @return The default table name.
@@ -430,23 +391,22 @@
         _jdbcTableName = tableName;
     }
 
-    protected void initialise(String tableName) throws Exception
+    protected void initialise() throws ObjectStoreException
     {
-        String jdbcAccessClassName = getAccessClassName();
-
-        if (jdbcAccessClassName == null)
-        {
-            throw new FatalError(tsLogger.i18NLogger.get_objectstore_JDBCStore_5());
+        if(jdbcStoreEnvironmentBean.getJdbcUserDbAccess() == null) {
+            throw new ObjectStoreException(tsLogger.i18NLogger.get_objectstore_JDBCStore_5());
+        } else {
+            setJDBCAccess(jdbcStoreEnvironmentBean.getJdbcUserDbAccess());
         }
 
         try
         {
-            setupStore(jdbcAccessClassName, tableName);
+            setupStore();
         }
         catch (Exception e)
         {
             tsLogger.i18NLogger.fatal_objectstore_JDBCStore_1(getJDBCAccess().toString(), getTableName());
-            throw e;
+            throw new ObjectStoreException(e);
         }
 
         _isValid = true;
@@ -457,62 +417,18 @@
     * we will exit.
     */
     @SuppressWarnings("unchecked")
-    protected void setupStore(String jdbcAccessClassName, String tableName)
-            throws Exception
+    protected void setupStore() throws Exception
     {
-        if (jdbcAccessClassName == null || jdbcAccessClassName.length() == 0)
-            throw new ObjectStoreException();
-
-        final JDBCAccess jdbcAccess;
-        synchronized (_theAccesses)
+        String impleTableName = getDefaultTableName();
+        final String jdbcAccessTableName = getJDBCAccess().tableName();
+        if ((jdbcAccessTableName != null) && (jdbcAccessTableName.length() > 0))
         {
-            final Object jdbcAccessObject = _theAccesses
-                    .get(jdbcAccessClassName);
-            if (jdbcAccessObject != null)
-            {
-                jdbcAccess = (JDBCAccess) jdbcAccessObject;
-            }
-            else
-            {
-                try
-                {
-                    final Class jdbcAccessClass = Thread.currentThread()
-                            .getContextClassLoader().loadClass(
-                                    jdbcAccessClassName);
-                    jdbcAccess = (JDBCAccess) jdbcAccessClass.newInstance();
-                }
-                catch (final Exception ex)
-                {
-                    tsLogger.i18NLogger.fatal_objectstore_JDBCStore_2(jdbcAccessClassName, ex);
-                    throw ex;
-                }
-                _theAccesses.put(jdbcAccessClassName, jdbcAccess);
-            }
+            impleTableName = jdbcAccessTableName;
         }
-        setJDBCAccess(jdbcAccess);
 
-        final String impleTableName;
-        if ((tableName != null) && (tableName.length() > 0))
-        {
-            impleTableName = tableName;
-        }
-        else
-        {
-            final String jdbcAccessTableName = jdbcAccess.tableName();
-            if ((jdbcAccessTableName != null)
-                    && (jdbcAccessTableName.length() > 0))
-            {
-                impleTableName = jdbcAccessTableName;
-            }
-            else
-            {
-                impleTableName = getDefaultTableName();
-            }
-        }
-
         setTableName(impleTableName);
 
-        final String impleKey = jdbcAccessClassName + ":" + impleTableName;
+        final String impleKey = getStoreName();
 
         synchronized (_theImples)
         {
@@ -532,7 +448,7 @@
 
                     try
                     {
-                        connection = jdbcAccess.getConnection();
+                        connection = getJDBCAccess().getConnection();
                     }
                     catch (final SQLException sqle)
                     {
@@ -562,7 +478,7 @@
                             throw ex;
                         }
 
-                        if (!jdbcImple.initialise(connection, jdbcAccess,
+                        if (!jdbcImple.initialise(connection, getJDBCAccess(),
                                 impleTableName, jdbcStoreEnvironmentBean)) {
                             tsLogger.i18NLogger.warn_objectstore_JDBCStore_3();
                             throw new ObjectStoreException();
@@ -672,8 +588,6 @@
 
     private JDBCAccess _jdbcAccess;
 
-    private String _jdbcAccessClassName;
-
     private String _jdbcTableName;
 
     private static String _defaultTableName = "JBossTSTable";
@@ -685,6 +599,4 @@
     */
 
     protected static final HashMap _theImples = new HashMap();
-
-    protected static final HashMap _theAccesses = new HashMap();
 }

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/objectstore/jdbc/JDBCStoreEnvironmentBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/objectstore/jdbc/JDBCStoreEnvironmentBean.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/objectstore/jdbc/JDBCStoreEnvironmentBean.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -21,6 +21,8 @@
 package com.arjuna.ats.internal.arjuna.objectstore.jdbc;
 
 import com.arjuna.ats.arjuna.objectstore.StateType;
+import com.arjuna.ats.internal.arjuna.common.ClassloadingUtility;
+import com.arjuna.ats.arjuna.objectstore.jdbc.JDBCAccess;
 
 /**
  * A JavaBean containing configuration properties for the JDBC based objectstore implementation.
@@ -29,8 +31,11 @@
  */
 public class JDBCStoreEnvironmentBean
 {
-    private volatile String jdbcUserDbAccess = null;
-    private volatile String jdbcTxDbAccess = null;
+    private volatile String jdbcUserDbAccessClassName = null;
+    private volatile JDBCAccess jdbcUserDbAccess;
+    private volatile String jdbcTxDbAccessClassName = null;
+    private volatile JDBCAccess jdbcTxDbAccess;
+
     private volatile int jdbcPoolSizeInitial = 1;
     private volatile int jdbcPoolSizeMaximum = 1;
     private volatile boolean jdbcPoolPutConnections = false;
@@ -38,51 +43,169 @@
     private volatile int share = StateType.OS_UNSHARED;
 
     /**
-     * Returns the classname of the JDBCAccess implementation used for the ObjectStore.
+     * Returns the class name of the JDBCAccess implementation used for the ObjectStore.
      *
      * Default: null
-     * Equivalent deprecated property: com.arjuna.ats.arjuna.objectstore.jdbcUserDbAccess
+     * Equivalent deprecated property: com.arjuna.ats.arjuna.objectstore.jdbcUserDbAccessClassName
      *
      * @return the name of a class implementing JDBCAccess.
      */
-    public String getJdbcUserDbAccess()
+    public String getJdbcUserDbAccessClassName()
     {
+        return jdbcUserDbAccessClassName;
+    }
+
+    /**
+     * Sets the class name of the JDBCAccess implementation used for the ObjectStore.
+     *
+     * @param jdbcUserDbAccessClassName the name of the class implementing JDBCAccess.
+     */
+    public void setJdbcUserDbAccessClassName(String jdbcUserDbAccessClassName)
+    {
+        synchronized(this)
+        {
+            if(jdbcUserDbAccessClassName == null)
+            {
+                this.jdbcUserDbAccess = null;
+            }
+            else if(!jdbcUserDbAccessClassName.equals(this.jdbcUserDbAccessClassName))
+            {
+                this.jdbcUserDbAccess = null;
+            }
+            this.jdbcUserDbAccessClassName = jdbcUserDbAccessClassName;
+        }
+    }
+
+    /**
+     * Returns an instance of a class implementing JDBCAccess.
+     *
+     * If there is no pre-instantiated instance set and classloading or instantiation fails,
+     * this method will log an appropriate warning and return null, not throw an exception.
+     *
+     * @return a JDBCAccess implementation instance, or null.
+     */
+    public JDBCAccess getJdbcUserDbAccess()
+    {
+        if(jdbcUserDbAccess == null && jdbcUserDbAccessClassName != null)
+        {
+            synchronized (this) {
+                if(jdbcUserDbAccess == null && jdbcUserDbAccessClassName != null) {
+                    JDBCAccess instance = ClassloadingUtility.loadAndInstantiateClass(JDBCAccess.class, jdbcUserDbAccessClassName, null);
+                    jdbcUserDbAccess = instance;
+                }
+            }
+        }
+
         return jdbcUserDbAccess;
     }
 
     /**
-     * Sets the classname of the JDBCAccess implementation used for the ObjectStore.
+     * Sets the instance of JDBCAccess
      *
-     * @param jdbcUserDbAccess the name of the class implementing JDBCAccess.
+     * @param instance an Object that implements JDBCAccess, or null.
      */
-    public void setJdbcUserDbAccess(String jdbcUserDbAccess)
+    public void setJdbcUserDbAccess(JDBCAccess instance)
     {
-        this.jdbcUserDbAccess = jdbcUserDbAccess;
+        synchronized(this)
+        {
+            JDBCAccess oldInstance = this.jdbcUserDbAccess;
+            jdbcUserDbAccess = instance;
+
+            if(instance == null)
+            {
+                this.jdbcUserDbAccessClassName = null;
+            }
+            else if(instance != oldInstance)
+            {
+                String name = ClassloadingUtility.getNameForClass(instance);
+                this.jdbcUserDbAccessClassName = name;
+            }
+        }
     }
 
+
     /**
-     * Returns the classname of the JDBCAccess implementation used for the ActionStore.
+     * Returns the class name of the JDBCAccess implementation used for the ActionStore.
      *
      * Default: null
-     * Equivalent deprecated property: com.arjuna.ats.arjuna.objectstore.jdbcTxDbAccess
+     * Equivalent deprecated property: com.arjuna.ats.arjuna.objectstore.jdbcTxDbAccessClassName
      *
      * @return the name of a class implementing JDBCAccess.
      */
-    public String getJdbcTxDbAccess()
+    public String getJdbcTxDbAccessClassName()
     {
+        return jdbcTxDbAccessClassName;
+    }
+
+    /**
+     * Sets the class name of the JDBCAccess implementation used for the ActionStore.
+     *
+     * @param jdbcTxDbAccessClassName the name of the class implementing JDBCAccess.
+     */
+    public void setJdbcTxDbAccessClassName(String jdbcTxDbAccessClassName)
+    {
+        synchronized(this)
+        {
+            if(jdbcTxDbAccessClassName == null)
+            {
+                this.jdbcTxDbAccess = null;
+            }
+            else if(!jdbcTxDbAccessClassName.equals(this.jdbcTxDbAccessClassName))
+            {
+                this.jdbcTxDbAccess = null;
+            }
+            this.jdbcTxDbAccessClassName = jdbcTxDbAccessClassName;
+        }
+    }
+
+   /**
+     * Returns an instance of a class implementing JDBCAccess.
+     *
+     * If there is no pre-instantiated instance set and classloading or instantiation fails,
+     * this method will log an appropriate warning and return null, not throw an exception.
+     *
+     * @return a JDBCAccess implementation instance, or null.
+     */
+    public JDBCAccess getJdbcTxDbAccess()
+    {
+          if(jdbcTxDbAccess == null && jdbcTxDbAccessClassName != null)
+        {
+            synchronized (this) {
+                if(jdbcTxDbAccess == null && jdbcTxDbAccessClassName != null) {
+                    JDBCAccess instance = ClassloadingUtility.loadAndInstantiateClass(JDBCAccess.class, jdbcTxDbAccessClassName, null);
+                    jdbcTxDbAccess = instance;
+                }
+            }
+        }
+
         return jdbcTxDbAccess;
     }
 
     /**
-     * Sets the classname of the JDBCAccess implementation used for the ActionStore.
+     * Sets the instance of JDBCAccess
      *
-     * @param jdbcTxDbAccess the name of the class implementing JDBCAccess.
+     * @param instance an Object that implements JDBCAccess, or null.
      */
-    public void setJdbcTxDbAccess(String jdbcTxDbAccess)
+    public void setJdbcTxDbAccess(JDBCAccess instance)
     {
-        this.jdbcTxDbAccess = jdbcTxDbAccess;
+        synchronized(this)
+        {
+            JDBCAccess oldInstance = this.jdbcTxDbAccess;
+            jdbcTxDbAccess = instance;
+
+            if(instance == null)
+            {
+                this.jdbcTxDbAccessClassName = null;
+            }
+            else if(instance != oldInstance)
+            {
+                String name = ClassloadingUtility.getNameForClass(instance);
+                this.jdbcTxDbAccessClassName = name;
+            }
+        }
     }
 
+
     /**
      * Returns the number of connections to initialize in the pool at startup.
      *

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/ExpiredEntryMonitor.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/ExpiredEntryMonitor.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/ExpiredEntryMonitor.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -236,64 +236,16 @@
         initialised = true;
     }
 
-  private static void loadScanners()
-  {
-      _expiryScanners = new Vector();
+    private static void loadScanners()
+    {
+        _expiryScanners = new Vector();
 
-      for(String scannerName : recoveryPropertyManager.getRecoveryEnvironmentBean().getExpiryScanners()) {
-          loadScanner(scannerName);
-      }
-  }
-    
-  private static void loadScanner( String className )
-  {
-      if (tsLogger.logger.isDebugEnabled()) {
-          tsLogger.logger.debug("Loading expiry scanner "+className);
-      }
-      
-      if (className == null) {
-          tsLogger.i18NLogger.warn_recovery_ExpiredEntryMonitor_7();
-
-          return;
-      }
-      else
-      {
-          try
-	  {
-	      Class c = Thread.currentThread().getContextClassLoader().loadClass( className );
-		
-		try
-		{
-		   ExpiryScanner m = (ExpiryScanner) c.newInstance();
-		   
-		   if ( m.toBeUsed() )
-		   {
-			   _expiryScanners.add( m );
-		   }
-		   else
-		   {
-		       if (tsLogger.logger.isDebugEnabled()) {
-                   tsLogger.logger.debug("Loading expiry scanner "+className);
-               }
-		   }
-		}
-		catch (ClassCastException e) {
-            tsLogger.i18NLogger.warn_recovery_ExpiredEntryMonitor_9(className);
+        for(ExpiryScanner scanner : recoveryPropertyManager.getRecoveryEnvironmentBean().getExpiryScanners()) {
+            if ( scanner.toBeUsed() ) {
+                _expiryScanners.add( scanner );
+            }
         }
-		catch (IllegalAccessException e1) {
-            tsLogger.i18NLogger.warn_recovery_ExpiredEntryMonitor_6(e1);
-        }
-		catch (InstantiationException e2) {
-            tsLogger.i18NLogger.warn_recovery_ExpiredEntryMonitor_6(e2);
-        }
-		
-		c = null;
-	  }
-	  catch (ClassNotFoundException e) {
-          tsLogger.i18NLogger.warn_recovery_ExpiredEntryMonitor_10(className);
-      }
-      }
-  }
+    }
 
     /**
      * flag which causes the next scan to be skipped if it is true. this is set from _skipFirst when a

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/PeriodicRecovery.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/PeriodicRecovery.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/PeriodicRecovery.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -858,60 +858,10 @@
      */
     private void loadModules ()
     {
-        Vector<String> moduleNames = new Vector<String>(recoveryPropertyManager.getRecoveryEnvironmentBean().getRecoveryExtensions());
-
-        for(String moduleName : moduleNames) {
-            loadModule(moduleName);
-        }
+        _recoveryModules.addAll(recoveryPropertyManager.getRecoveryEnvironmentBean().getRecoveryModules());
     }
 
     /**
-     * load a specific recovery module and add it to the recovery modules list
-     *
-     * @param className
-     */
-   private void loadModule (String className)
-   {
-       if (tsLogger.logger.isDebugEnabled()) {
-           tsLogger.logger.debug("Loading recovery module " +
-                   className);
-       }
-
-      if (className == null) {
-          tsLogger.i18NLogger.warn_recovery_PeriodicRecovery_1();
-
-          return;
-      }
-      else
-      {
-         try
-         {
-	     Class c = Thread.currentThread().getContextClassLoader().loadClass( className );
-
-            try
-            {
-               RecoveryModule m = (RecoveryModule) c.newInstance();
-               _recoveryModules.add(m);
-            }
-            catch (ClassCastException e) {
-                tsLogger.i18NLogger.warn_recovery_PeriodicRecovery_2(className);
-            }
-            catch (IllegalAccessException iae) {
-                tsLogger.i18NLogger.warn_recovery_PeriodicRecovery_3(iae);
-            }
-            catch (InstantiationException ie) {
-                tsLogger.i18NLogger.warn_recovery_PeriodicRecovery_4(ie);
-            }
-
-            c = null;
-         }
-         catch ( ClassNotFoundException cnfe ) {
-             tsLogger.i18NLogger.warn_recovery_PeriodicRecovery_5(className);
-         }
-      }
-   }
-
-    /**
      * initialise the periodic recovery instance to a suitable initial state
      */
    private void initialise ()

Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/RecActivatorLoader.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/RecActivatorLoader.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/RecActivatorLoader.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -47,7 +47,7 @@
     // These are loaded in list iteration order.
     private void loadRecoveryActivators ()
     {
-        List<String> activatorNames = recoveryPropertyManager.getRecoveryEnvironmentBean().getRecoveryActivators();
+        List<String> activatorNames = recoveryPropertyManager.getRecoveryEnvironmentBean().getRecoveryActivatorClassNames();
 
         for(String activatorName : activatorNames) {
             RecoveryActivator recoveryActivator = ClassloadingUtility.loadAndInstantiateClass(RecoveryActivator.class, activatorName, null);

Modified: labs/jbosstm/trunk/ArjunaCore/docs/ArjunaCore_Development_Guide/en-US/Appendix_Class_Definitions.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/docs/ArjunaCore_Development_Guide/en-US/Appendix_Class_Definitions.xml	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaCore/docs/ArjunaCore_Development_Guide/en-US/Appendix_Class_Definitions.xml	2011-03-03 14:37:59 UTC (rev 36775)
@@ -1,4 +1,4 @@
-<?xml version='1.0' encoding='utf-8' ?>
+ <?xml version='1.0' encoding='utf-8' ?>
 <!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
 <!ENTITY % BOOK_ENTITIES SYSTEM "ArjunaCore_Development_Guide.ent">
 %BOOK_ENTITIES;

Modified: labs/jbosstm/trunk/ArjunaCore/docs/ArjunaCore_Development_Guide/en-US/Appendix_Object_Store_Implementations.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/docs/ArjunaCore_Development_Guide/en-US/Appendix_Object_Store_Implementations.xml	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaCore/docs/ArjunaCore_Development_Guide/en-US/Appendix_Object_Store_Implementations.xml	2011-03-03 14:37:59 UTC (rev 36775)
@@ -201,7 +201,7 @@
         </para>
         <para>
           The implementation of the <interfacename>JDBCAccess</interfacename> interface to use should be set in the
-          <varname>ObjectStoreEnvironmentBean.jdbcUserDbAccess</varname> property variable.
+          <varname>ObjectStoreEnvironmentBean.jdbcUserDbAccessClassName</varname> property variable.
         </para>
         <para>
           If overriding the object store implementation, the type of this object store is <type>JDBCStore</type>.
@@ -209,7 +209,7 @@
         <para>
           A JDBC object store can be used for managing the transaction log. In this case, the transaction log
           implementation should be set to <literal>JDBCActionStore</literal> and the <classname>JDBCAccess</classname>
-          implementation must be provided via the <varname>ObjectStoreEnvironmentBean.jdbcTxDbAccess property</varname>
+          implementation must be provided via the <varname>ObjectStoreEnvironmentBean.jdbcTxDbAccessClassName property</varname>
           variable. In this case, the default table name is <systemitem>JBossTSTxTable</systemitem>.
         </para>
         <para>

Modified: labs/jbosstm/trunk/ArjunaCore/docs/ArjunaCore_Development_Guide/en-US/extras/EnvironmentBeans.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/docs/ArjunaCore_Development_Guide/en-US/extras/EnvironmentBeans.xml	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaCore/docs/ArjunaCore_Development_Guide/en-US/extras/EnvironmentBeans.xml	2011-03-03 14:37:59 UTC (rev 36775)
@@ -1,4 +1,4 @@
-<entry key="RecoveryEnvironmentBean.recoveryExtensions">
+<entry key="RecoveryEnvironmentBean.recoveryModuleClassNames">
   com.arjuna.ats.internal.arjuna.recovery.AtomicActionRecoveryModule
   com.arjuna.ats.internal.txoj.recovery.TORecoveryModule
 </entry>
\ No newline at end of file

Modified: labs/jbosstm/trunk/ArjunaCore/docs/ArjunaCore_Installation_And_Administration_Guide/en-US/Failure_Recovery_Administration.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/docs/ArjunaCore_Installation_And_Administration_Guide/en-US/Failure_Recovery_Administration.xml	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaCore/docs/ArjunaCore_Installation_And_Administration_Guide/en-US/Failure_Recovery_Administration.xml	2011-03-03 14:37:59 UTC (rev 36775)
@@ -154,7 +154,7 @@
       <application>ArjunaCore</application>. These modules support various aspects of transaction recovery, including
       JDBC recovery. It is possible for advanced users to create their own recovery modules and register them with the
       Recovery Manager. The recovery modules are registered with the RecoveryManager using
-      <methodname>RecoveryEnvironmentBean.recoveryExtensions</methodname>. These will be invoked on each pass of the
+      <methodname>RecoveryEnvironmentBean.recoveryModuleClassNames</methodname>. These will be invoked on each pass of the
       periodic recovery in the sort-order of the property names – it is thus possible to predict the ordering, but a
       failure in an application process might occur while a periodic recovery pass is in progress. The default Recovery
       Extension settings are:
@@ -172,7 +172,7 @@
       old. Scans and removals are performed by implementations of the
       <interfacename>com.arjuna.ats.arjuna.recovery.ExpiryScanner</interfacename> interface. These implementations are
       loaded by giving the class names as the value of a property
-      <property>RecoveryEnvironmentBean.expiryScanners</property>. The RecoveryManager calls the
+      <property>RecoveryEnvironmentBean.expiryScannerClassNames</property>. The RecoveryManager calls the
       <methodname>scan()</methodname><!-- I don't like using brackets unless the method never has any parameters -->
       method on each loaded Expiry Scanner implementation at an interval determined by the property
       <property>RecoveryEnvironmentBean.expiryScanInterval</property>. This value is given in hours, and defaults to

Modified: labs/jbosstm/trunk/ArjunaCore/docs/ArjunaCore_Installation_And_Administration_Guide/en-US/extras/default_recovery_extension_settings.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/docs/ArjunaCore_Installation_And_Administration_Guide/en-US/extras/default_recovery_extension_settings.xml	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaCore/docs/ArjunaCore_Installation_And_Administration_Guide/en-US/extras/default_recovery_extension_settings.xml	2011-03-03 14:37:59 UTC (rev 36775)
@@ -1,4 +1,4 @@
-<entry key="RecoveryEnvironmentBean.recoveryExtensions">
+<entry key="RecoveryEnvironmentBean.recoveryModuleClassNames">
     com.arjuna.ats.internal.arjuna.recovery.AtomicActionRecoveryModule
     com.arjuna.ats.internal.txoj.recovery.TORecoveryModule
 </entry>

Modified: labs/jbosstm/trunk/ArjunaCore/docs/ArjunaCore_Installation_And_Administration_Guide/en-US/extras/expiry_scanner_properties.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/docs/ArjunaCore_Installation_And_Administration_Guide/en-US/extras/expiry_scanner_properties.xml	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaCore/docs/ArjunaCore_Installation_And_Administration_Guide/en-US/extras/expiry_scanner_properties.xml	2011-03-03 14:37:59 UTC (rev 36775)
@@ -1,3 +1,3 @@
-<entry key="RecoveryEnvironmentBean.expiryScanners">
+<entry key="RecoveryEnvironmentBean.expiryScannerClassNames">
     com.arjuna.ats.internal.arjuna.recovery.ExpiredTransactionStatusManagerScanner
 </entry>
\ No newline at end of file

Modified: labs/jbosstm/trunk/ArjunaCore/jbossts-properties-arjunacore.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/jbossts-properties-arjunacore.xml	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaCore/jbossts-properties-arjunacore.xml	2011-03-03 14:37:59 UTC (rev 36775)
@@ -80,18 +80,18 @@
          on recovery modules and their configuration when running in various
          deployments.
     -->
-    <entry key="RecoveryEnvironmentBean.recoveryExtensions">
+    <entry key="RecoveryEnvironmentBean.recoveryModuleClassNames">
         com.arjuna.ats.internal.arjuna.recovery.AtomicActionRecoveryModule
         com.arjuna.ats.internal.txoj.recovery.TORecoveryModule
     </entry>
 
     <!-- Expiry scanners to use (order of invocation is random). -->
-    <entry key="RecoveryEnvironmentBean.expiryScanners">
+    <entry key="RecoveryEnvironmentBean.expiryScannerClassNames">
         com.arjuna.ats.internal.arjuna.recovery.ExpiredTransactionStatusManagerScanner
     </entry>
 
     <!--
-        Add the following to the set of expiryScanners above to move logs that cannot be completed by failure recovery.
+        Add the following to the set of expiryScannerClassNames above to move logs that cannot be completed by failure recovery.
             But be sure you know what you are doing and why!
              com.arjuna.ats.internal.arjuna.recovery.AtomicActionExpiryScanner
     -->

Modified: labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Installation_And_Administration_Guide/en-US/Failure_Recovery_Administration.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Installation_And_Administration_Guide/en-US/Failure_Recovery_Administration.xml	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Installation_And_Administration_Guide/en-US/Failure_Recovery_Administration.xml	2011-03-03 14:37:59 UTC (rev 36775)
@@ -156,7 +156,7 @@
       <application>ArjunaTA</application>. These modules support various aspects of transaction recovery, including JDBC
       recovery. It is possible for advanced users to create their own recovery modules and register them with the
       Recovery Manager. The recovery modules are registered with the RecoveryManager using
-      <methodname>RecoveryEnvironmentBean.recoveryExtensions</methodname>. These will be invoked on each pass of the
+      <methodname>RecoveryEnvironmentBean.recoveryModuleClassNames</methodname>. These will be invoked on each pass of the
       periodic recovery in the sort-order of the property names – it is thus possible to predict the ordering, but a
       failure in an application process might occur while a periodic recovery pass is in progress. The default Recovery
       Extension settings are:
@@ -174,7 +174,7 @@
       old. Scans and removals are performed by implementations of the
       <interfacename>com.arjuna.ats.arjuna.recovery.ExpiryScanner</interfacename> interface. These implementations are
       loaded by giving the class names as the value of a property
-      <property>RecoveryEnvironmentBean.expiryScanners</property>. The RecoveryManager calls the
+      <property>RecoveryEnvironmentBean.expiryScannerClassNames</property>. The RecoveryManager calls the
       <methodname>scan()</methodname><!-- I don't like using brackets unless the method never has any parameters -->
       method on each loaded Expiry Scanner implementation at an interval determined by the property
       <property>RecoveryEnvironmentBean.expiryScanInterval</property>. This value is given in hours, and defaults to

Modified: labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Installation_And_Administration_Guide/en-US/extras/default_recovery_extension_settings.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Installation_And_Administration_Guide/en-US/extras/default_recovery_extension_settings.xml	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Installation_And_Administration_Guide/en-US/extras/default_recovery_extension_settings.xml	2011-03-03 14:37:59 UTC (rev 36775)
@@ -1,4 +1,4 @@
-<entry key="RecoveryEnvironmentBean.recoveryExtensions">
+<entry key="RecoveryEnvironmentBean.recoveryModuleClassNames">
     com.arjuna.ats.internal.arjuna.recovery.AtomicActionRecoveryModule
     com.arjuna.ats.internal.txoj.recovery.TORecoveryModule
     com.arjuna.ats.internal.jta.recovery.arjunacore.XARecoveryModule

Modified: labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Installation_And_Administration_Guide/en-US/extras/expiry_scanner_properties.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Installation_And_Administration_Guide/en-US/extras/expiry_scanner_properties.xml	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTA/docs/ArjunaTA_Installation_And_Administration_Guide/en-US/extras/expiry_scanner_properties.xml	2011-03-03 14:37:59 UTC (rev 36775)
@@ -1,3 +1,3 @@
-<entry key="RecoveryEnvironmentBean.expiryScanners">
+<entry key="RecoveryEnvironmentBean.expiryScannerClassNames">
     com.arjuna.ats.internal.arjuna.recovery.ExpiredTransactionStatusManagerScanner
 </entry>
\ No newline at end of file

Modified: labs/jbosstm/trunk/ArjunaJTA/jbossts-properties-arjunajta.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jbossts-properties-arjunajta.xml	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTA/jbossts-properties-arjunajta.xml	2011-03-03 14:37:59 UTC (rev 36775)
@@ -88,19 +88,19 @@
          on recovery modules and their configuration when running in various
          deployments.
     -->
-    <entry key="RecoveryEnvironmentBean.recoveryExtensions">
+    <entry key="RecoveryEnvironmentBean.recoveryModuleClassNames">
         com.arjuna.ats.internal.arjuna.recovery.AtomicActionRecoveryModule
         com.arjuna.ats.internal.txoj.recovery.TORecoveryModule
         com.arjuna.ats.internal.jta.recovery.arjunacore.XARecoveryModule
     </entry>
 
     <!-- Expiry scanners to use (order of invocation is random). -->
-    <entry key="RecoveryEnvironmentBean.expiryScanners">
+    <entry key="RecoveryEnvironmentBean.expiryScannerClassNames">
         com.arjuna.ats.internal.arjuna.recovery.ExpiredTransactionStatusManagerScanner
     </entry>
 
     <!--
-        Add the following to the set of expiryScanners above to move logs that cannot be completed by failure recovery.
+        Add the following to the set of expiryScannerClassNames above to move logs that cannot be completed by failure recovery.
             But be sure you know what you are doing and why!
              com.arjuna.ats.internal.arjuna.recovery.AtomicActionExpiryScanner
     -->

Modified: labs/jbosstm/trunk/ArjunaJTA/jdbc/classes/com/arjuna/ats/internal/jdbc/DirectRecoverableConnection.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jdbc/classes/com/arjuna/ats/internal/jdbc/DirectRecoverableConnection.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTA/jdbc/classes/com/arjuna/ats/internal/jdbc/DirectRecoverableConnection.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -31,6 +31,7 @@
 
 package com.arjuna.ats.internal.jdbc;
 
+import com.arjuna.ats.internal.arjuna.common.ClassloadingUtility;
 import com.arjuna.ats.jdbc.logging.*;
 
 import com.arjuna.ats.internal.jdbc.drivers.modifiers.ConnectionModifier;
@@ -340,9 +341,11 @@
 	    {
 		if (_theDataSource == null)
 		{
-		    Class c = Thread.currentThread().getContextClassLoader().loadClass(_dynamic);
+		    _dynamicConnection = ClassloadingUtility.loadAndInstantiateClass(DynamicClass.class, _dynamic, null);
+            if(_dynamicConnection == null) {
+                throw new SQLException(jdbcLogger.i18NLogger.get_dynamicerror());
+            }
 
-		    _dynamicConnection = (DynamicClass) c.newInstance();
 		    _theDataSource = _dynamicConnection.getDataSource(_dbName);
 		}
 

Modified: labs/jbosstm/trunk/ArjunaJTA/jdbc/classes/com/arjuna/ats/internal/jdbc/drivers/modifiers/ModifierFactory.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jdbc/classes/com/arjuna/ats/internal/jdbc/drivers/modifiers/ModifierFactory.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTA/jdbc/classes/com/arjuna/ats/internal/jdbc/drivers/modifiers/ModifierFactory.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -31,6 +31,7 @@
 
 package com.arjuna.ats.internal.jdbc.drivers.modifiers;
 
+import com.arjuna.ats.internal.arjuna.common.ClassloadingUtility;
 import com.arjuna.ats.internal.jdbc.drivers.modifiers.list;
 
 import java.util.*;
@@ -53,18 +54,17 @@
 
     public static synchronized void putModifier (String dbName, int major, int minor, String modclass)
     {
-	try {
-		Object mod = Thread.currentThread().getContextClassLoader().loadClass(modclass).newInstance();
-	_modifiers.put(dbName+"_"+major+"_"+minor, mod);
-	} catch (Exception e) {
-	}
+        ConnectionModifier connectionModifier = ClassloadingUtility.loadAndInstantiateClass(ConnectionModifier.class, modclass, null);
+        if(connectionModifier != null) {
+            _modifiers.put(dbName+"_"+major+"_"+minor, connectionModifier);
+        }
     }
 
     /*
      * Convert input to lower case first.
      */
     
-    public static synchronized Object getModifier (String dbName, int major, int minor)
+    public static synchronized ConnectionModifier getModifier (String dbName, int major, int minor)
     {
 	String exactMatch = null;
 	String majorMatch = null;
@@ -95,11 +95,5 @@
 	return null;
     }    
 
-    private static Hashtable _modifiers = new Hashtable();
-
-    static
-    {
-	Object o = new list();
-    }
-    
+    private static Hashtable<String,ConnectionModifier> _modifiers = new Hashtable<String,ConnectionModifier>();
 }

Modified: labs/jbosstm/trunk/ArjunaJTA/jdbc/classes/com/arjuna/ats/jdbc/logging/jdbcI18NLogger.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jdbc/classes/com/arjuna/ats/jdbc/logging/jdbcI18NLogger.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTA/jdbc/classes/com/arjuna/ats/jdbc/logging/jdbcI18NLogger.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -90,7 +90,7 @@
 //	@LogMessage(level = WARN)
 //	public void warn_drivers_invaliddb();
 
-	@Message(id = 17016, value = "No dynamic class specified!", format = MESSAGE_FORMAT)
+	@Message(id = 17016, value = "Failed to load dynamic class", format = MESSAGE_FORMAT)
 	public String get_dynamicerror();
 
 	@Message(id = 17017, value = "enlist of resource failed", format = MESSAGE_FORMAT)

Modified: labs/jbosstm/trunk/ArjunaJTA/jdbc/classes/com/arjuna/ats/jdbc/logging/jdbcI18NLoggerImpl.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jdbc/classes/com/arjuna/ats/jdbc/logging/jdbcI18NLoggerImpl.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTA/jdbc/classes/com/arjuna/ats/jdbc/logging/jdbcI18NLoggerImpl.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -89,7 +89,7 @@
 	}
 
 	public String get_dynamicerror() {
-		return "ARJUNA-17016 No dynamic class specified!";
+		return "ARJUNA-17016 Failed to load dynamic class";
 	}
 
 	public String get_enlistfailed() {

Modified: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore/XARecoveryModule.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore/XARecoveryModule.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/recovery/arjunacore/XARecoveryModule.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -62,9 +62,8 @@
 {
     public XARecoveryModule()
 	{
-		this(
-				com.arjuna.ats.internal.jta.recovery.arjunacore.XARecoveryResourceManagerImple.class
-						.getName(), "Local XARecoveryModule");
+		this(new com.arjuna.ats.internal.jta.recovery.arjunacore.XARecoveryResourceManagerImple(),
+                "Local XARecoveryModule");
 
 		com.arjuna.ats.internal.jta.Implementations.initialise();
 	}
@@ -202,22 +201,13 @@
 		return null;
 	}
 
-	protected XARecoveryModule(String recoveryClass, String logName)
+	protected XARecoveryModule(XARecoveryResourceManager recoveryClass, String logName)
     {
         _logName = logName;
-
-        try
-        {
-            Class c = Thread.currentThread().getContextClassLoader().loadClass(
-                    recoveryClass);
-
-            _recoveryManagerClass = (XARecoveryResourceManager) c.newInstance();
+        _recoveryManagerClass = recoveryClass;
+        if(_recoveryManagerClass == null) {
+            jtaLogger.i18NLogger.warn_recovery_constfail();
         }
-        catch (Exception ex)
-        {
-            jtaLogger.i18NLogger.warn_recovery_constfail(ex);
-            _recoveryManagerClass = null;
-        }
 
         _xaRecoverers = jtaPropertyManager.getJTAEnvironmentBean().getXaResourceRecoveries();
         _xaResourceOrphanFilters = jtaPropertyManager.getJTAEnvironmentBean().getXaResourceOrphanFilters();

Modified: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/arjunacore/XAOnePhaseResource.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/arjunacore/XAOnePhaseResource.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/arjunacore/XAOnePhaseResource.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -46,6 +46,7 @@
 import com.arjuna.ats.arjuna.coordinator.TwoPhaseOutcome;
 import com.arjuna.ats.arjuna.state.InputObjectState;
 import com.arjuna.ats.arjuna.state.OutputObjectState;
+import com.arjuna.ats.internal.arjuna.common.ClassloadingUtility;
 import com.arjuna.ats.jta.logging.jtaLogger;
 import com.arjuna.ats.jta.utils.XAHelper;
 import com.arjuna.ats.jta.xa.RecoverableXAConnection;
@@ -252,29 +253,11 @@
         {
             case RecoverableXAConnection.AUTO_RECOVERY:
                 final String recoverableXAConnectionClassName = is.unpackString() ;
-                final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader() ;
-                final Class recoverableXAConnectionClass ;
-                try
-                {
-                    recoverableXAConnectionClass = contextClassLoader.loadClass(recoverableXAConnectionClassName) ;
-                }
-                catch (final ClassNotFoundException cnfe)
-                {
-                    throw generateUnpackError(cnfe) ;
-                }
 
-                try
-                {
-                    recoverableXAConnection = (RecoverableXAConnection)recoverableXAConnectionClass.newInstance() ;
+                recoverableXAConnection = ClassloadingUtility.loadAndInstantiateClass(RecoverableXAConnection.class, recoverableXAConnectionClassName, null);
+                if(recoverableXAConnection == null) {
+                    throw generateUnpackError(new ClassNotFoundException());
                 }
-                catch (final InstantiationException ie)
-                {
-                    throw generateUnpackError(ie) ;
-                }
-                catch (final IllegalAccessException iae)
-                {
-                    throw generateUnpackError(iae) ;
-                }
 
                 recoverableXAConnection.unpackFrom(is) ;
                 try

Modified: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/arjunacore/XAResourceRecord.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/arjunacore/XAResourceRecord.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/internal/jta/resources/arjunacore/XAResourceRecord.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -31,6 +31,7 @@
 
 package com.arjuna.ats.internal.jta.resources.arjunacore;
 
+import com.arjuna.ats.internal.arjuna.common.ClassloadingUtility;
 import com.arjuna.ats.jta.recovery.*;
 
 import com.arjuna.ats.jta.common.jtaPropertyManager;
@@ -925,10 +926,11 @@
 			else
 			{
 				String creatorName = os.unpackString();
-				Class c = Thread.currentThread().getContextClassLoader()
-						.loadClass(creatorName);
 
-				_recoveryObject = (RecoverableXAConnection) c.newInstance();
+                _recoveryObject = ClassloadingUtility.loadAndInstantiateClass(RecoverableXAConnection.class, creatorName, null);
+                if(_recoveryObject == null) {
+                    throw new ClassNotFoundException();
+                }
 
 				_recoveryObject.unpackFrom(os);
 				_theXAResource = _recoveryObject.getResource();

Modified: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/common/JTAEnvironmentBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/common/JTAEnvironmentBean.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/common/JTAEnvironmentBean.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -497,7 +497,7 @@
         {
             if(xaResourceOrphanFilterClassNames == null)
             {
-                this.xaResourceOrphanFilters = null;
+                this.xaResourceOrphanFilters = new ArrayList<XAResourceOrphanFilter>();
                 this.xaResourceOrphanFilterClassNames = new ArrayList<String>();
             }
             else if(!xaResourceOrphanFilterClassNames.equals(this.xaResourceOrphanFilterClassNames))
@@ -787,7 +787,7 @@
      * Default: null.
      * Equivalent deprecated property: com.arjuna.ats.jta.lastResourceOptimisationInterfaceClassName
      *
-     * @return the classname of the market interface for LastResource handling.
+     * @return the class name of the market interface for LastResource handling.
      */
     public String getLastResourceOptimisationInterfaceClassName()
     {
@@ -821,7 +821,7 @@
      * If there is no Class set and loading fails, this method will log an appropriate warning
      * and return null, not throw an exception.
      *
-     * @return the LastResource market interface.
+     * @return the LastResource marker interface.
      */
     public Class getLastResourceOptimisationInterface()
     {
@@ -839,10 +839,24 @@
     /**
      * Sets a Class to use as the marker interface for LastResource
      *
-     * @param lastResourceOptimisationInterface a marker interface Class, or null.
+     * @param clazz a marker interface Class, or null.
      */
-    public void setLastResourceOptimisationInterface(Class lastResourceOptimisationInterface)
+    public void setLastResourceOptimisationInterface(Class clazz)
     {
-        this.lastResourceOptimisationInterface = lastResourceOptimisationInterface;
+        synchronized(this)
+        {
+            Class oldClazz = this.lastResourceOptimisationInterface;
+            lastResourceOptimisationInterface = clazz;
+
+            if(clazz == null)
+            {
+                this.lastResourceOptimisationInterfaceClassName = null;
+            }
+            else if(clazz != oldClazz)
+            {
+                String name = ClassloadingUtility.getNameForClass(clazz);
+                this.lastResourceOptimisationInterfaceClassName = name;
+            }
+        }
     }
 }

Modified: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/logging/jtaI18NLogger.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/logging/jtaI18NLogger.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/logging/jtaI18NLogger.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -54,7 +54,7 @@
 
 	@Message(id = 16004, value = "XARecoveryModule setup failed", format = MESSAGE_FORMAT)
 	@LogMessage(level = WARN)
-	public void warn_recovery_constfail(@Cause() Throwable arg0);
+	public void warn_recovery_constfail();
 
 	@Message(id = 16005, value = "{0} - failed to recover XAResource. status is ${1}", format = MESSAGE_FORMAT)
 	@LogMessage(level = WARN)

Modified: labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/logging/jtaI18NLoggerImpl.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/logging/jtaI18NLoggerImpl.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTA/jta/classes/com/arjuna/ats/jta/logging/jtaI18NLoggerImpl.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -49,8 +49,8 @@
 		logger.logv(WARN, "ARJUNA-16002 Cannot add resource to table: no XID value available.", (Object)null);
 	}
 
-	public void warn_recovery_constfail(Throwable arg0) {
-		logger.logv(WARN, arg0, "ARJUNA-16004 XARecoveryModule setup failed", (Object)null);
+	public void warn_recovery_constfail() {
+		logger.logv(WARN, "ARJUNA-16004 XARecoveryModule setup failed", (Object)null);
 	}
 
 	public void warn_recovery_failedtorecover(String arg0, String arg1) {

Modified: labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Development_Guide/en-US/Failure_Recovery.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Development_Guide/en-US/Failure_Recovery.xml	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Development_Guide/en-US/Failure_Recovery.xml	2011-03-03 14:37:59 UTC (rev 36775)
@@ -250,7 +250,7 @@
         JBossTS includes several recovery modules, supporting various aspects of transaction recovery including JDBC
         recovery. You can create your own recovery modules and register them with the
         <classname>RecoveryManager</classname> using the
-        <classname>RecoveryEnvironmentBean.recoveryExtensions</classname> property. These recovery modules are invoked
+        <classname>RecoveryEnvironmentBean.recoveryModuleClassNames</classname> property. These recovery modules are invoked
         on each pass of the periodic recovery in the order they appear. You can predict the order in which they run, but
         a failure in an application process might occur while a periodic recovery pass is in progress. The default
         <classname>RecoveryExtension</classname> settings are below.
@@ -455,7 +455,7 @@
         for these and removing items that are very old. Scans and removals are performed by implementations of the
         <interfacename>>com.arjuna.ats.arjuna.recovery.ExpiryScanner</interfacename>. Implementations of this interface
         are loaded by giving the class names as the value of the property
-        <varname>RecoveryEnvironmentBean.expiryScanners</varname>. The <classname>RecoveryManager</classname> calls the
+        <varname>RecoveryEnvironmentBean.expiryScannerClassNames</varname>. The <classname>RecoveryManager</classname> calls the
         <methodname>scan</methodname> method on each loaded <classname>ExpiryScanner</classname> implementation at an
         interval determined by the property <varname>RecoveryEnvironmentBean.expiryScanInterval</varname>. This value is
         given in hours, and defaults to <literal>12</literal>. A property value of <literal>0</literal> disables any

Modified: labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Development_Guide/en-US/extras/ExpiryScanner-properties.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Development_Guide/en-US/extras/ExpiryScanner-properties.xml	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Development_Guide/en-US/extras/ExpiryScanner-properties.xml	2011-03-03 14:37:59 UTC (rev 36775)
@@ -1,4 +1,4 @@
-<entry key="RecoveryEnvironmentBean.expiryScanners">
+<entry key="RecoveryEnvironmentBean.expiryScannerClassNames">
   com.arjuna.ats.internal.arjuna.recovery.ExpiredTransactionStatusManagerScanner
   com.arjuna.ats.internal.jts.recovery.contact.ExpiredContactScanner
   com.arjuna.ats.internal.jts.recovery.transactions.ExpiredToplevelScanner

Modified: labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Development_Guide/en-US/extras/RecoveryManager-properties.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Development_Guide/en-US/extras/RecoveryManager-properties.xml	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Development_Guide/en-US/extras/RecoveryManager-properties.xml	2011-03-03 14:37:59 UTC (rev 36775)
@@ -1,3 +1,3 @@
-<entry key="RecoveryEnvironmentBean.recoveryActivators">
+<entry key="RecoveryEnvironmentBean.recoveryActivatorClassNames">
   com.arjuna.ats.internal.jts.orbspecific.recovery.RecoveryEnablement
 </entry>
\ No newline at end of file

Modified: labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Development_Guide/en-US/extras/default-RecoveryExtension-settings.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Development_Guide/en-US/extras/default-RecoveryExtension-settings.xml	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Development_Guide/en-US/extras/default-RecoveryExtension-settings.xml	2011-03-03 14:37:59 UTC (rev 36775)
@@ -1,4 +1,4 @@
-<entry key="RecoveryEnvironmentBean.recoveryExtensions">
+<entry key="RecoveryEnvironmentBean.recoveryModuleClassNames">
   com.arjuna.ats.internal.arjuna.recovery.AtomicActionRecoveryModule
   com.arjuna.ats.internal.txoj.recovery.TORecoveryModule
   com.arjuna.ats.internal.jts.recovery.transactions.TopLevelTransactionRecoveryModule

Modified: labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Installation_And_Administration_Guide/en-US/Failure_Recovery_Administration.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Installation_And_Administration_Guide/en-US/Failure_Recovery_Administration.xml	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Installation_And_Administration_Guide/en-US/Failure_Recovery_Administration.xml	2011-03-03 14:37:59 UTC (rev 36775)
@@ -154,7 +154,7 @@
       <application>ArjunaJTS</application>. These modules support various aspects of transaction recovery, including
       JDBC recovery. It is possible for advanced users to create their own recovery modules and register them with the
       Recovery Manager. The recovery modules are registered with the RecoveryManager using
-      <methodname>RecoveryEnvironmentBean.recoveryExtensions</methodname>. These will be invoked on each pass of the
+      <methodname>RecoveryEnvironmentBean.recoveryModuleClassNames</methodname>. These will be invoked on each pass of the
       periodic recovery in the sort-order of the property names – it is thus possible to predict the ordering, but a
       failure in an application process might occur while a periodic recovery pass is in progress. The default Recovery
       Extension settings are:
@@ -172,7 +172,7 @@
       old. Scans and removals are performed by implementations of the
       <interfacename>com.arjuna.ats.arjuna.recovery.ExpiryScanner</interfacename> interface. These implementations are
       loaded by giving the class names as the value of a property
-      <property>RecoveryEnvironmentBean.expiryScanners</property>. The RecoveryManager calls the
+      <property>RecoveryEnvironmentBean.expiryScannerClassNames</property>. The RecoveryManager calls the
       <methodname>scan()</methodname><!-- I don't like using brackets unless the method never has any parameters -->
       method on each loaded Expiry Scanner implementation at an interval determined by the property
       <property>RecoveryEnvironmentBean.expiryScanInterval</property>. This value is given in hours, and defaults to

Modified: labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Installation_And_Administration_Guide/en-US/extras/default_recovery_extension_settings.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Installation_And_Administration_Guide/en-US/extras/default_recovery_extension_settings.xml	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Installation_And_Administration_Guide/en-US/extras/default_recovery_extension_settings.xml	2011-03-03 14:37:59 UTC (rev 36775)
@@ -1,4 +1,4 @@
-<entry key="RecoveryEnvironmentBean.recoveryExtensions">
+<entry key="RecoveryEnvironmentBean.recoveryModuleClassNames">
   com.arjuna.ats.internal.arjuna.recovery.AtomicActionRecoveryModule
   com.arjuna.ats.internal.txoj.recovery.TORecoveryModule
   com.arjuna.ats.internal.jts.recovery.transactions.TopLevelTransactionRecoveryModule

Modified: labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Installation_And_Administration_Guide/en-US/extras/expiry_scanner_properties.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Installation_And_Administration_Guide/en-US/extras/expiry_scanner_properties.xml	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTS/docs/ArjunaJTS_Installation_And_Administration_Guide/en-US/extras/expiry_scanner_properties.xml	2011-03-03 14:37:59 UTC (rev 36775)
@@ -1,3 +1,3 @@
-<entry key="RecoveryEnvironmentBean.expiryScanners">
+<entry key="RecoveryEnvironmentBean.expiryScannerClassNames">
     com.arjuna.ats.internal.arjuna.recovery.ExpiredTransactionStatusManagerScanner
 </entry>
\ No newline at end of file

Modified: labs/jbosstm/trunk/ArjunaJTS/jbossts-properties-arjunajts.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jbossts-properties-arjunajts.xml	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTS/jbossts-properties-arjunajts.xml	2011-03-03 14:37:59 UTC (rev 36775)
@@ -88,7 +88,7 @@
          on recovery modules and their configuration when running in various
          deployments.
     -->
-    <entry key="RecoveryEnvironmentBean.recoveryExtensions">
+    <entry key="RecoveryEnvironmentBean.recoveryModuleClassNames">
         com.arjuna.ats.internal.arjuna.recovery.AtomicActionRecoveryModule
         com.arjuna.ats.internal.txoj.recovery.TORecoveryModule
         com.arjuna.ats.internal.jts.recovery.transactions.TopLevelTransactionRecoveryModule
@@ -97,7 +97,7 @@
     </entry>
 
     <!-- Expiry scanners to use (order of invocation is random). -->
-    <entry key="RecoveryEnvironmentBean.expiryScanners">
+    <entry key="RecoveryEnvironmentBean.expiryScannerClassNames">
         com.arjuna.ats.internal.arjuna.recovery.ExpiredTransactionStatusManagerScanner
         com.arjuna.ats.internal.jts.recovery.contact.ExpiredContactScanner
         com.arjuna.ats.internal.jts.recovery.transactions.ExpiredToplevelScanner
@@ -105,7 +105,7 @@
     </entry>
 
     <!--
-        Add the following to the set of expiryScanners above to move logs that cannot be completed by failure recovery.
+        Add the following to the set of expiryScannerClassNames above to move logs that cannot be completed by failure recovery.
             But be sure you know what you are doing and why!
              com.arjuna.ats.internal.arjuna.recovery.AtomicActionExpiryScanner
     -->
@@ -141,7 +141,7 @@
 
 
     <!-- Recovery Activators to use. -->
-    <entry key="RecoveryEnvironmentBean.recoveryActivators">com.arjuna.ats.internal.jts.orbspecific.recovery.RecoveryEnablement</entry>
+    <entry key="RecoveryEnvironmentBean.recoveryActivatorClassNames">com.arjuna.ats.internal.jts.orbspecific.recovery.RecoveryEnablement</entry>
 
 
 	<entry key="JTAEnvironmentBean.transactionManagerClassName">com.arjuna.ats.internal.jta.transaction.jts.TransactionManagerImple</entry>

Modified: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/recovery/jts/XARecoveryModule.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/recovery/jts/XARecoveryModule.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/recovery/jts/XARecoveryModule.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -41,9 +41,8 @@
 
 	public XARecoveryModule ()
 	{
-		super(
-				com.arjuna.ats.internal.jta.recovery.jts.XARecoveryResourceManagerImple.class
-						.getName(), "JTS XARecoveryModule");
+		super(new com.arjuna.ats.internal.jta.recovery.jts.XARecoveryResourceManagerImple(),
+                "JTS XARecoveryModule");
 
 		com.arjuna.ats.internal.jta.Implementationsx.initialise();
 	}

Modified: labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jts/orbspecific/XAResourceRecord.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jts/orbspecific/XAResourceRecord.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTS/jtax/classes/com/arjuna/ats/internal/jta/resources/jts/orbspecific/XAResourceRecord.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -33,6 +33,7 @@
 
 import com.arjuna.ats.arjuna.objectstore.ParticipantStore;
 import com.arjuna.ats.arjuna.objectstore.StoreManager;
+import com.arjuna.ats.internal.arjuna.common.ClassloadingUtility;
 import com.arjuna.ats.jta.recovery.*;
 
 import com.arjuna.ats.jta.common.jtaPropertyManager;
@@ -959,10 +960,11 @@
 			else
 			{
 				String creatorName = os.unpackString();
-				Class c = Thread.currentThread().getContextClassLoader()
-						.loadClass(creatorName);
 
-				_recoveryObject = (RecoverableXAConnection) c.newInstance();
+                _recoveryObject = ClassloadingUtility.loadAndInstantiateClass(RecoverableXAConnection.class, creatorName, null);
+                if(_recoveryObject == null) {
+                    throw new ClassNotFoundException();
+                }
 
 				_recoveryObject.unpackFrom(os);
 				_theXAResource = _recoveryObject.getResource();

Modified: labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/orbspecific/recovery/RecoveryEnablement.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/orbspecific/recovery/RecoveryEnablement.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/orbspecific/recovery/RecoveryEnablement.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -33,6 +33,7 @@
 package com.arjuna.ats.internal.jts.orbspecific.recovery;
 
 import com.arjuna.ats.arjuna.recovery.RecoveryActivator;
+import com.arjuna.ats.internal.arjuna.common.ClassloadingUtility;
 import com.arjuna.ats.jts.logging.*;
 
 import com.arjuna.orbportability.*;
@@ -75,7 +76,7 @@
 
     public RecoveryEnablement ()
     {
-	Implementations.initialise();
+        Implementations.initialise();
     }
 
     /**
@@ -86,12 +87,12 @@
 
     public static void isNotANormalProcess()
     {
-	_isNormalProcess = false;
+        _isNormalProcess = false;
     }
 
     public static boolean isNormalProcess ()
     {
-	return _isNormalProcess;
+        return _isNormalProcess;
     }
 
     /**
@@ -109,28 +110,25 @@
         String theClassName = null;
 
         // The class that should start the service shall not be called directly. An intermediate class shall be used
-        try
+        switch (orbType)
         {
-            switch (orbType)
+            case ORBType.JACORB:
             {
-                case ORBType.JACORB:
-                {
-                    theClassName = "com.arjuna.ats.internal.jts.orbspecific.jacorb.recoverycoordinators.JacOrbRCServiceInit";
-                    recoveryService = (RecoveryServiceInit) Thread.currentThread().getContextClassLoader().loadClass(theClassName).newInstance();
+                theClassName = "com.arjuna.ats.internal.jts.orbspecific.jacorb.recoverycoordinators.JacOrbRCServiceInit";
+                recoveryService = ClassloadingUtility.loadAndInstantiateClass(RecoveryServiceInit.class, theClassName, null);
+                if(recoveryService == null) {
+                    jtsLogger.i18NLogger.warn_recovery_RecoveryEnablement_6();
+                } else {
                     outcome = recoveryService.startRCservice();
                 }
-                break;
-                default: {
-                    jtsLogger.i18NLogger.warn_recovery_RecoveryEnablement_1();
-                    outcome = false;
-                }
-                break;
             }
+            break;
+            default: {
+                jtsLogger.i18NLogger.warn_recovery_RecoveryEnablement_1();
+                outcome = false;
+            }
+            break;
         }
-        catch (Exception e)
-        {
-            jtsLogger.i18NLogger.warn_recovery_RecoveryEnablement_6(e);
-        }
 
         return outcome;
     }
@@ -140,45 +138,45 @@
      */
     public static String getRecoveryManagerTag()
     {
-	if (_RecoveryManagerTag != null) {
-	    return _RecoveryManagerTag;
-	} else {
-	    return null;
-	}
+        if (_RecoveryManagerTag != null) {
+            return _RecoveryManagerTag;
+        } else {
+            return null;
+        }
     }
 
     static{
 
-	// tell the recovery init we aren't a normal TS-user
-	RecoveryEnablement.isNotANormalProcess();
-	RecoveryInit.isNotANormalProcess();
+        // tell the recovery init we aren't a normal TS-user
+        RecoveryEnablement.isNotANormalProcess();
+        RecoveryInit.isNotANormalProcess();
 
-	// see if there is a property defining the recoverymanager
-	// servicename
+        // see if there is a property defining the recoverymanager
+        // servicename
 
-	//	_RecoveryManagerTag = System.getProperty(RecoveryEnvironment.RECOVERY_MANAGER_TAG);
+        //	_RecoveryManagerTag = System.getProperty(RecoveryEnvironment.RECOVERY_MANAGER_TAG);
 
-	if (_RecoveryManagerTag == null)
-	{
-	    // if no property, use the hostname/ip address
+        if (_RecoveryManagerTag == null)
+        {
+            // if no property, use the hostname/ip address
 
-	    InetAddress thisAddress = null;
-	    try
-	    {
-		thisAddress = InetAddress.getLocalHost();
-		_RecoveryManagerTag = thisAddress.getHostName();
-	    }
-	    catch (UnknownHostException uhe)
-	    {
-		uhe.printStackTrace();
-	    }
+            InetAddress thisAddress = null;
+            try
+            {
+                thisAddress = InetAddress.getLocalHost();
+                _RecoveryManagerTag = thisAddress.getHostName();
+            }
+            catch (UnknownHostException uhe)
+            {
+                uhe.printStackTrace();
+            }
 
-	}
-	// prune off any spaces
-	if (_RecoveryManagerTag != null)
-	{
-	    _RecoveryManagerTag =_RecoveryManagerTag.trim();
-	}
+        }
+        // prune off any spaces
+        if (_RecoveryManagerTag != null)
+        {
+            _RecoveryManagerTag =_RecoveryManagerTag.trim();
+        }
     }
 
 }

Modified: labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/recovery/RecoveryInit.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/recovery/RecoveryInit.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/internal/jts/recovery/RecoveryInit.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -31,6 +31,7 @@
 
 package com.arjuna.ats.internal.jts.recovery;
 
+import com.arjuna.ats.internal.arjuna.common.ClassloadingUtility;
 import com.arjuna.ats.jts.logging.*;
 
 import com.arjuna.orbportability.common.opPropertyManager;
@@ -76,9 +77,6 @@
 	    // the eventhandler is the same for all orbs (at the moment)
 	    String eventHandlerClassName = "com.arjuna.ats.internal.jts.recovery.contact.RecoveryContactWriter";
 
-	    Object recoveryCoordinatorInitialiser = null;
-	    String InitClassName = null;
-
 	    if ( _isNormalProcess)
 	    {
 		try
@@ -92,8 +90,9 @@
 		    {
 		    case ORBType.JACORB:
 			{
-			    InitClassName = "com.arjuna.ats.internal.jts.orbspecific.jacorb.recoverycoordinators.JacOrbRecoveryInit";
-			    recoveryCoordinatorInitialiser = Thread.currentThread().getContextClassLoader().loadClass(InitClassName).newInstance();
+			    String initClassName = "com.arjuna.ats.internal.jts.orbspecific.jacorb.recoverycoordinators.JacOrbRecoveryInit";
+                Class recoveryCoordinatorInitialiser = ClassloadingUtility.loadClass(initClassName);
+                recoveryCoordinatorInitialiser.newInstance();
 			}
 			break;
 		    default: {
@@ -104,9 +103,9 @@
 
 		    // register the ContactWriter to watch for the first ArjunaFactory construction
 
-            List<String> eventHandlers = opPropertyManager.getOrbPortabilityEnvironmentBean().getEventHandlers();
+            List<String> eventHandlers = opPropertyManager.getOrbPortabilityEnvironmentBean().getEventHandlerClassNames();
             eventHandlers.add(eventHandlerClassName);
-		    opPropertyManager.getOrbPortabilityEnvironmentBean().setEventHandlers(eventHandlers);
+		    opPropertyManager.getOrbPortabilityEnvironmentBean().setEventHandlerClassNames(eventHandlers);
 
 		    // Change here above the way to call this startRCService -
 		    // otherwise call it in JacOrbRecoveryInit above.

Modified: labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/jts/logging/jtsI18NLogger.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/jts/logging/jtsI18NLogger.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/jts/logging/jtsI18NLogger.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -501,9 +501,9 @@
 //	@LogMessage(level = WARN)
 //	public void warn_recovery_RecoveryEnablement_5(String arg0);
 
-	@Message(id = 22121, value = "The Recovery Service Initialisation failed}", format = MESSAGE_FORMAT)
+	@Message(id = 22121, value = "The Recovery Service Initialisation failed", format = MESSAGE_FORMAT)
 	@LogMessage(level = WARN)
-	public void warn_recovery_RecoveryEnablement_6(@Cause() Throwable arg0);
+	public void warn_recovery_RecoveryEnablement_6();
 
 //	@Message(id = 22122, value = "added ORBAttribute for recoveryCoordinatorInitialiser", format = MESSAGE_FORMAT)
 //	@LogMessage(level = WARN)

Modified: labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/jts/logging/jtsI18NLoggerImpl.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/jts/logging/jtsI18NLoggerImpl.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTS/jts/classes/com/arjuna/ats/jts/logging/jtsI18NLoggerImpl.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -433,8 +433,8 @@
         logger.logv(WARN, "ARJUNA-22116 Could not locate supported ORB for RecoveryCoordinator initialisation.", (Object)null);
     }
 
-    public void warn_recovery_RecoveryEnablement_6(Throwable arg0) {
-        logger.logv(WARN, arg0, "ARJUNA-22121 The Recovery Service Initialisation failed}", (Object)null);
+    public void warn_recovery_RecoveryEnablement_6() {
+        logger.logv(WARN, "ARJUNA-22121 The Recovery Service Initialisation failed", (Object)null);
     }
 
     public void fatal_recovery_RecoveryInit_4() {

Modified: labs/jbosstm/trunk/ArjunaJTS/orbportability/build.xml
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/orbportability/build.xml	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTS/orbportability/build.xml	2011-03-03 14:37:59 UTC (rev 36775)
@@ -28,6 +28,7 @@
 
         <import-module.macro module="common"/>
         <import-module.macro module="common_tests"/>
+        <import-module.macro module="arjuna"/>
 
     </target>
 

Modified: labs/jbosstm/trunk/ArjunaJTS/orbportability/classes/com/arjuna/orbportability/common/OrbPortabilityEnvironmentBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/orbportability/classes/com/arjuna/orbportability/common/OrbPortabilityEnvironmentBean.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTS/orbportability/classes/com/arjuna/orbportability/common/OrbPortabilityEnvironmentBean.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -20,8 +20,10 @@
  */
 package com.arjuna.orbportability.common;
 
+import com.arjuna.ats.internal.arjuna.common.ClassloadingUtility;
 import com.arjuna.common.internal.util.propertyservice.PropertyPrefix;
 import com.arjuna.common.internal.util.propertyservice.ConcatenationPrefix;
+import com.arjuna.orbportability.event.EventHandler;
 
 import java.util.*;
 
@@ -39,7 +41,8 @@
     private volatile String resolveService = "CONFIGURATION_FILE";
 
     @ConcatenationPrefix(prefix = "com.arjuna.orbportability.eventHandler")
-    private volatile List<String> eventHandlers = new ArrayList<String>();
+    private volatile List<String> eventHandlerClassNames = new ArrayList<String>();
+    private volatile List<EventHandler> eventHandlers = null;
 
     private volatile String orbImplementation = null;
     private volatile String oaImplementation = null;
@@ -141,7 +144,7 @@
     }
 
     /**
-     * Returns the classnames for the ORB object connect/disconnect event handlers.
+     * Returns the class names for the ORB object connect/disconnect event handlers.
      * The returned list is a copy. May return an empty list, will not return null.
      *
      * Default: empty list.
@@ -149,28 +152,84 @@
      *
      * @return a list of names of classes, being implementations of the EventHandler interface.
      */
-    public List<String> getEventHandlers()
+    public List<String> getEventHandlerClassNames()
     {
-        return new ArrayList<String>(eventHandlers);
+        synchronized(this) {
+            return new ArrayList<String>(eventHandlerClassNames);
+        }
     }
 
     /**
-     * Sets the classnames of the ORB object connect/disconnect event handlers.
+     * Sets the class names of the ORB object connect/disconnect event handlers.
      * List elements should be names of classes that implement EventHandler.
      * The provided list will be copied, not retained.
      *
-     * @param eventHandlers a list of EventHandler implementation classnames.
+     * @param eventHandlerClassNames a list of EventHandler implementation classnames.
      */
-    public void setEventHandlers(List<String> eventHandlers)
+    public void setEventHandlerClassNames(List<String> eventHandlerClassNames)
     {
-        if(eventHandlers == null) {
-            this.eventHandlers = new ArrayList<String>();
-        } else {
-            this.eventHandlers = new ArrayList<String>(eventHandlers);
+        synchronized(this)
+        {
+            if(eventHandlerClassNames == null)
+            {
+                this.eventHandlers = new ArrayList<EventHandler>();
+                this.eventHandlerClassNames = new ArrayList<String>();
+            }
+            else if(!eventHandlerClassNames.equals(this.eventHandlerClassNames))
+            {
+                this.eventHandlers = null;
+                this.eventHandlerClassNames = new ArrayList<String>(eventHandlerClassNames);
+            }
         }
     }
 
     /**
+     * Returns the set of EventHandler instances.
+     * The returned list is a copy. May return an empty list, will not return null.
+     *
+     * If there is no pre-instantiated instance set and classloading or instantiation of one or more
+     * elements fails, this method will log an appropriate warning and return a non-null set with
+     * fewer elements.
+     *
+     * @return the set of EventHandler instances.
+     */
+    public List<EventHandler> getEventHandlers()
+    {
+        synchronized(this)
+        {
+            if(eventHandlers == null) {
+                List<EventHandler> instances = ClassloadingUtility.loadAndInstantiateClassesWithInit(EventHandler.class, eventHandlerClassNames);
+                eventHandlers = instances;
+            }
+            return new ArrayList<EventHandler>(eventHandlers);
+        }
+    }
+
+    /**
+     * Sets the instances of EventHandler.
+     * The provided list will be copied, not retained.
+     *
+     * @param eventHandlers the set of EventHandler instances.
+     */
+    public void setEventHandlers(List<EventHandler> eventHandlers)
+    {
+        synchronized(this)
+        {
+            if(eventHandlers == null)
+            {
+                this.eventHandlers = new ArrayList<EventHandler>();
+                this.eventHandlerClassNames = new ArrayList<String>();
+            }
+            else
+            {
+                this.eventHandlers = new ArrayList<EventHandler>(eventHandlers);
+                List<String> names = ClassloadingUtility.getNamesForClasses(this.eventHandlers);
+                this.eventHandlerClassNames = names;
+            }
+        }
+    }
+
+    /**
      * Returns the classname of the ORBImple implementation.
      *
      * Default: null (i.e. use classpath based selection)

Modified: labs/jbosstm/trunk/ArjunaJTS/orbportability/classes/com/arjuna/orbportability/common/OrbPortabilityEnvironmentBeanMBean.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/orbportability/classes/com/arjuna/orbportability/common/OrbPortabilityEnvironmentBeanMBean.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTS/orbportability/classes/com/arjuna/orbportability/common/OrbPortabilityEnvironmentBeanMBean.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -38,7 +38,7 @@
 
     String getResolveService();
 
-    List<String> getEventHandlers();
+    List<String> getEventHandlerClassNames();
 
     String getOrbImplementation();
 

Modified: labs/jbosstm/trunk/ArjunaJTS/orbportability/classes/com/arjuna/orbportability/event/EventManager.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/orbportability/classes/com/arjuna/orbportability/event/EventManager.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTS/orbportability/classes/com/arjuna/orbportability/event/EventManager.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -156,20 +156,8 @@
     {
         _handlers = new Hashtable();
 
-        // load handler classes:
-        for(String handlerName : opPropertyManager.getOrbPortabilityEnvironmentBean().getEventHandlers())
-        {
-            try
-            {
-                Class c = Thread.currentThread().getContextClassLoader().loadClass(handlerName);
-                EventHandler h = (EventHandler) c.newInstance();
-
-                addHandler(h);
-            }
-            catch (Exception ex)
-            {
-                opLogger.i18NLogger.warn_event_EventManager_caughtexceptionfor("EventManager", handlerName, ex);
-            }
+        for(EventHandler eventHandler : opPropertyManager.getOrbPortabilityEnvironmentBean().getEventHandlers()) {
+            addHandler(eventHandler);
         }
     }
     

Modified: labs/jbosstm/trunk/ArjunaJTS/orbportability/classes/com/arjuna/orbportability/internal/utils/InitLoader.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/orbportability/classes/com/arjuna/orbportability/internal/utils/InitLoader.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTS/orbportability/classes/com/arjuna/orbportability/internal/utils/InitLoader.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -31,6 +31,7 @@
 
 package com.arjuna.orbportability.internal.utils;
 
+import com.arjuna.ats.internal.arjuna.common.ClassloadingUtility;
 import com.arjuna.orbportability.common.opPropertyManager;
 import com.arjuna.orbportability.logging.opLogger;
 import com.arjuna.orbportability.utils.InitClassInterface;
@@ -78,41 +79,34 @@
 	    return;
 	}
 	else
-	{
-	    try
-	    {
-            opLogger.i18NLogger.info_internal_utils_InitLoader_loading(initName, className);
+    {
+        opLogger.i18NLogger.info_internal_utils_InitLoader_loading(initName, className);
 
-		Class c = Thread.currentThread().getContextClassLoader().loadClass(className);
+        Class c = ClassloadingUtility.loadClass(className);
+        if(c == null) {
+            return;
+        }
+        try
+        {
+            Object o = c.newInstance();
 
-		try
-		{
-		    Object o = c.newInstance();
+            if ( o instanceof InitClassInterface )
+            {
+                ((InitClassInterface)o).invoke(initObj);
+            }
 
-                    if ( o instanceof InitClassInterface )
-                    {
-                        ((InitClassInterface)o).invoke(initObj);
-                    }
-
-		    o = null;
-		}
-		catch (IllegalAccessException e1)
-		{
+            o = null;
+        }
+        catch (IllegalAccessException e1)
+        {
             opLogger.i18NLogger.warn_internal_utils_InitLoader_exception(initName, e1);
-		}
-		catch (InstantiationException e2)
-		{
+        }
+        catch (InstantiationException e2)
+        {
             opLogger.i18NLogger.warn_internal_utils_InitLoader_exception(initName, e2);
-		}
-
-		c = null;
-	    }
-	    catch (ClassNotFoundException e)
-	    {
-            opLogger.i18NLogger.warn_internal_utils_InitLoader_couldnotfindclass(initName, className);
-	    }
-	}
+        }
     }
+    }
 
 private String initName;
 private String propertyName;

Modified: labs/jbosstm/trunk/ArjunaJTS/orbportability/classes/com/arjuna/orbportability/logging/orbportabilityI18NLogger.java
===================================================================
--- labs/jbosstm/trunk/ArjunaJTS/orbportability/classes/com/arjuna/orbportability/logging/orbportabilityI18NLogger.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/ArjunaJTS/orbportability/classes/com/arjuna/orbportability/logging/orbportabilityI18NLogger.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -115,9 +115,9 @@
 	@LogMessage(level = WARN)
 	public void warn_common_Configuration_bindDefault_invalidbind(String arg0);
 
-	@Message(id = 21020, value = "{0} - caught exception for {1}", format = MESSAGE_FORMAT)
-	@LogMessage(level = WARN)
-	public void warn_event_EventManager_caughtexceptionfor(String arg0, String arg1, @Cause() Throwable arg2);
+//	@Message(id = 21020, value = "{0} - caught exception for {1}", format = MESSAGE_FORMAT)
+//	@LogMessage(level = WARN)
+//	public void warn_event_EventManager_caughtexceptionfor(String arg0, String arg1, @Cause() Throwable arg2);
 
 	@Message(id = 21021, value = "{0} - for: {1} threw exception", format = MESSAGE_FORMAT)
 	@LogMessage(level = WARN)
@@ -131,9 +131,9 @@
 	@LogMessage(level = WARN)
 	public void warn_internal_orbspecific_oa_implementations(String arg0);
 
-	@Message(id = 21024, value = "{0} - could not find class {1}", format = MESSAGE_FORMAT)
-	@LogMessage(level = WARN)
-	public void warn_internal_utils_InitLoader_couldnotfindclass(String arg0, String arg1);
+//	@Message(id = 21024, value = "{0} - could not find class {1}", format = MESSAGE_FORMAT)
+//	@LogMessage(level = WARN)
+//	public void warn_internal_utils_InitLoader_couldnotfindclass(String arg0, String arg1);
 
 	@Message(id = 21025, value = "Exception whilst loading {1}", format = MESSAGE_FORMAT)
 	@LogMessage(level = WARN)

Modified: labs/jbosstm/trunk/atsintegration/transaction-jboss-beans.xml
===================================================================
--- labs/jbosstm/trunk/atsintegration/transaction-jboss-beans.xml	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/atsintegration/transaction-jboss-beans.xml	2011-03-03 14:37:59 UTC (rev 36775)
@@ -50,7 +50,7 @@
             </value-factory>
         </property>
 
-        <property name="recoveryExtensions" preinstantiate="false">
+        <property name="recoveryModuleClassNames" preinstantiate="false">
             <list elementClass="java.lang.String">
                 <value>com.arjuna.ats.internal.arjuna.recovery.AtomicActionRecoveryModule</value>
                 <value>com.arjuna.ats.internal.txoj.recovery.TORecoveryModule</value>
@@ -58,13 +58,13 @@
             </list>
         </property>
 
-        <property name="expiryScanners" preinstantiate="false">
+        <property name="expiryScannerClassNames" preinstantiate="false">
             <list elementClass="java.lang.String">
                 <value>com.arjuna.ats.internal.arjuna.recovery.ExpiredTransactionStatusManagerScanner</value>
             </list>
         </property>
 
-        <property name="recoveryActivators">
+        <property name="recoveryActivatorClassNames">
             <null/>
         </property>
 

Modified: labs/jbosstm/trunk/atsintegration/transaction-jboss-beans.xml.jts
===================================================================
--- labs/jbosstm/trunk/atsintegration/transaction-jboss-beans.xml.jts	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/atsintegration/transaction-jboss-beans.xml.jts	2011-03-03 14:37:59 UTC (rev 36775)
@@ -50,7 +50,7 @@
             </value-factory>
         </property>
 
-        <property name="recoveryExtensions" preinstantiate="false">
+        <property name="recoveryModuleClassNames" preinstantiate="false">
             <list elementClass="java.lang.String">
                 <value>com.arjuna.ats.internal.arjuna.recovery.AtomicActionRecoveryModule</value>
                 <value>com.arjuna.ats.internal.txoj.recovery.TORecoveryModule</value>
@@ -60,7 +60,7 @@
             </list>
         </property>
 
-        <property name="expiryScanners" preinstantiate="false">
+        <property name="expiryScannerClassNames" preinstantiate="false">
             <list elementClass="java.lang.String">
                 <value>com.arjuna.ats.internal.arjuna.recovery.ExpiredTransactionStatusManagerScanner</value>
                 <value>com.arjuna.ats.internal.jts.recovery.contact.ExpiredContactScanner</value>
@@ -69,7 +69,7 @@
             </list>
         </property>
 
-        <property name="recoveryActivators" preinstantiate="false">
+        <property name="recoveryActivatorClassNames" preinstantiate="false">
             <list elementClass="java.lang.String">
                 <value>com.arjuna.ats.internal.jts.orbspecific.recovery.RecoveryEnablement</value>
             </list>

Modified: labs/jbosstm/trunk/qa/tests/src/org/jboss/jbossts/qa/Utils/EmptyObjectStore.java
===================================================================
--- labs/jbosstm/trunk/qa/tests/src/org/jboss/jbossts/qa/Utils/EmptyObjectStore.java	2011-03-03 14:32:19 UTC (rev 36774)
+++ labs/jbosstm/trunk/qa/tests/src/org/jboss/jbossts/qa/Utils/EmptyObjectStore.java	2011-03-03 14:37:59 UTC (rev 36775)
@@ -69,7 +69,7 @@
 			if (arjPropertyManager.getObjectStoreEnvironmentBean().getObjectStoreType() != null &&
 					arjPropertyManager.getObjectStoreEnvironmentBean().getObjectStoreType().startsWith("JDBCStore"))
 			{
-				JDBCAccess mJDBC = (JDBCAccess) Class.forName(new JDBCStoreEnvironmentBean().getJdbcUserDbAccess()).newInstance();
+				JDBCAccess mJDBC = (JDBCAccess) Class.forName(new JDBCStoreEnvironmentBean().getJdbcUserDbAccessClassName()).newInstance();
 				String tableName = mJDBC.tableName();
 				if (tableName == "")
 					/* from arjuna.internal.JDBCStore */



More information about the jboss-svn-commits mailing list