[jboss-svn-commits] JBL Code SVN: r19265 - in labs/jbosstm/trunk: ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/recovery and 6 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Thu Mar 27 11:54:55 EDT 2008
Author: adinn
Date: 2008-03-27 11:54:55 -0400 (Thu, 27 Mar 2008)
New Revision: 19265
Modified:
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/gandiva/inventory/Inventory.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/gandiva/inventory/InventoryImple.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/recovery/RecoveryManager.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/gandiva/inventory/DynamicInventory.java
labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/gandiva/inventory/StaticInventory.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/RecoveryManagerImple.java
labs/jbosstm/trunk/XTS/WSCF/classes/com/arjuna/mwlabs/wscf/model/twophase/arjunacore/ParticipantRecord.java
labs/jbosstm/trunk/XTS/sar/build.xml
labs/jbosstm/trunk/XTS/sar/src/org/jboss/transactions/XTSService.java
labs/jbosstm/trunk/XTS/sar/src/org/jboss/transactions/xts/recovery/ACCoordinatorRecoveryModule.java
labs/jbosstm/trunk/XTS/sar/src/org/jboss/transactions/xts/recovery/Implementations.java
Log:
fixed class loader issue which was caused by not removing and reinstalling Participant recordSetup class in the inventory. this resulted in the Participant bein gloaded using the classloader for the first sar rather than the subsequently reloaded sar which caused a cast exception. this now fixes JBTM-346. also enabled generation of debug info for the XTS sar module to help with debugging.
Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/gandiva/inventory/Inventory.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/gandiva/inventory/Inventory.java 2008-03-27 14:49:34 UTC (rev 19264)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/gandiva/inventory/Inventory.java 2008-03-27 15:54:55 UTC (rev 19265)
@@ -151,7 +151,23 @@
else
_imple.addToList(creator);
}
-
+
+ /**
+ * @message com.arjuna.ats.arjuna.gandiva.inventory.Inventory_2 [com.arjuna.ats.arjuna.gandiva.inventory.Inventory_2] - Inventory.removeFromList error - no implementation!
+ */
+public synchronized InventoryElement removeFromList (ClassName creatorClassName)
+ {
+ if (_imple == null)
+ {
+ if (tsLogger.arjLoggerI18N.isWarnEnabled())
+ tsLogger.arjLoggerI18N.warn("com.arjuna.ats.arjuna.gandiva.inventory.Inventory_2");
+
+ return null;
+ }
+ else
+ return _imple.removeFromList(creatorClassName);
+ }
+
public synchronized void printList (PrintStream toUse)
{
if (_imple == null)
Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/gandiva/inventory/InventoryImple.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/gandiva/inventory/InventoryImple.java 2008-03-27 14:49:34 UTC (rev 19264)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/gandiva/inventory/InventoryImple.java 2008-03-27 15:54:55 UTC (rev 19265)
@@ -95,6 +95,7 @@
Object[] paramResources);
public abstract void addToList (InventoryElement creator);
+public abstract InventoryElement removeFromList (ClassName creatorClassName);
public abstract void printList (PrintStream toUse);
public ClassName className ()
Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/recovery/RecoveryManager.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/recovery/RecoveryManager.java 2008-03-27 14:49:34 UTC (rev 19264)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/arjuna/recovery/RecoveryManager.java 2008-03-27 15:54:55 UTC (rev 19265)
@@ -218,12 +218,13 @@
/**
* Remove a recovery module from the system.
*
- * @param module The module to add.
+ * @param module The module to remove.
+ * @param waitOnScan true if the remove operation should wait for any in-progress scan to complete
*/
- public final void removeModule (RecoveryModule module)
+ public final void removeModule (RecoveryModule module, boolean waitOnScan)
{
- _theImple.removeModule(module);
+ _theImple.removeModule(module, waitOnScan);
}
/**
Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/gandiva/inventory/DynamicInventory.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/gandiva/inventory/DynamicInventory.java 2008-03-27 14:49:34 UTC (rev 19264)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/gandiva/inventory/DynamicInventory.java 2008-03-27 15:54:55 UTC (rev 19265)
@@ -73,6 +73,11 @@
_staticInventory.addToList(creator);
}
+ public synchronized InventoryElement removeFromList (ClassName creatorClassName)
+ {
+ return _staticInventory.removeFromList(creatorClassName);
+ }
+
public ClassName className ()
{
return ArjunaNames.Implementation_Inventory_DynamicInventory();
Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/gandiva/inventory/StaticInventory.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/gandiva/inventory/StaticInventory.java 2008-03-27 14:49:34 UTC (rev 19264)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/gandiva/inventory/StaticInventory.java 2008-03-27 15:54:55 UTC (rev 19265)
@@ -158,7 +158,43 @@
}
}
}
-
+
+ /**
+ * remove an inventory element with some given class name from the list
+ *
+ * this is required in order to support dynamic registration and deregistration of recovery modules.
+ * strictly we want the insertion of the recovery module into the recovery manager list and the
+ * insertion of the inventory element into this list to happen atomically but the two lists are
+ * currently independently managed. This needs resolving in the recovery module itself.
+ * @param creatorClassName
+ * @return the inventory element which has been removed or null if it is not found
+ */
+ public synchronized InventoryElement removeFromList(ClassName creatorClassName)
+ {
+ InventoryElement element = null;
+
+ if (creatorClassName != null)
+ {
+ InventoryList marker = headOfList, trail = null;
+
+ while (marker != null && !creatorClassName.equals(marker._instance.className())) {
+ trail = marker;
+ marker = marker._next;
+ }
+
+ if (marker != null) {
+ element = marker._instance;
+ if (trail != null) {
+ trail._next = marker._next;
+ } else {
+ headOfList = marker._next;
+ }
+ }
+ }
+
+ return element;
+ }
+
public synchronized void printList (PrintStream toUse)
{
InventoryList marker = headOfList;
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 2008-03-27 14:49:34 UTC (rev 19264)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/PeriodicRecovery.java 2008-03-27 15:54:55 UTC (rev 19265)
@@ -560,8 +560,9 @@
/**
* remove a recovery module from the recovery modules list
* @param module the module to be removed
+ * @param waitOnScan true if the remove operation should wait for any in-progress scan to complete
*/
- public final void removeModule (RecoveryModule module)
+ public final void removeModule (RecoveryModule module, boolean waitOnScan)
{
if (tsLogger.arjLogger.isDebugEnabled())
{
@@ -569,6 +570,13 @@
FacilityCode.FAC_CRASH_RECOVERY, "PeriodicRecovery: removing module " + module.getClass().getName());
}
_recoveryModules.remove(module);
+
+ if (waitOnScan) {
+ // make sure any scan which might be using the module has completed
+ synchronized (_stateLock) {
+ doScanningWait();
+ }
+ }
}
/**
@@ -715,7 +723,15 @@
{
RecoveryModule m = (RecoveryModule) modules.nextElement();
+ // we need to ensure we use the class loader context of the recovery module while we are executing
+ // its methods
+
+ ClassLoader cl = switchClassLoader(m);
+ try {
m.periodicWorkFirstPass();
+ } finally {
+ restoreClassLoader(cl);
+ }
if (tsLogger.arjLogger.isDebugEnabled())
{
@@ -761,7 +777,12 @@
{
RecoveryModule m = (RecoveryModule) modules.nextElement();
+ ClassLoader cl = switchClassLoader(m);
+ try {
m.periodicWorkSecondPass();
+ } finally {
+ restoreClassLoader(cl);
+ }
if (tsLogger.arjLogger.isDebugEnabled())
{
@@ -795,6 +816,41 @@
}
/**
+ * install the classloader associated with some specific recovery module as the current thread's class loader
+ *
+ * this avoids a problem where the background periodic recovery thread can see the same class as the recovery
+ * module's class loader, specifically where a the recovery module resides in a sar (e.g. the XTS code).
+ * If class with name "A" is loaded via the background thread class loader as A' and used to create instance
+ * a' then a cast expression in th erecovery code of the form (A)a' will try to resolve a' against version
+ * A'' loaded via the sar loader and get a class cast exception.
+ *
+ * @param rm the recovery module whose class loader is to be installed as the new thread class loader
+ * @return the class loader currently installed as the thread class loader
+ */
+
+ private ClassLoader switchClassLoader(RecoveryModule rm)
+ {
+ Thread currentThread = Thread.currentThread();
+ ClassLoader cl = currentThread.getContextClassLoader();
+
+ currentThread.setContextClassLoader(rm.getClass().getClassLoader());
+ return cl;
+ }
+
+ /**
+ * restore the current thread's classloader
+ *
+ * @param cl the class loader to be set as the current thread class loader
+ */
+
+ private void restoreClassLoader(ClassLoader cl)
+ {
+ Thread currentThread = Thread.currentThread();
+
+ currentThread.setContextClassLoader(cl);
+ }
+
+ /**
* Load recovery modules prior to starting to recovery. The property
* name of each module is used to indicate relative ordering.
*/
Modified: labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/RecoveryManagerImple.java
===================================================================
--- labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/RecoveryManagerImple.java 2008-03-27 14:49:34 UTC (rev 19264)
+++ labs/jbosstm/trunk/ArjunaCore/arjuna/classes/com/arjuna/ats/internal/arjuna/recovery/RecoveryManagerImple.java 2008-03-27 15:54:55 UTC (rev 19265)
@@ -167,9 +167,9 @@
_periodicRecovery.addModule(module);
}
- public final void removeModule (RecoveryModule module)
+ public final void removeModule (RecoveryModule module, boolean waitOnScan)
{
- _periodicRecovery.removeModule(module);
+ _periodicRecovery.removeModule(module, waitOnScan);
}
public final Vector getModules ()
Modified: labs/jbosstm/trunk/XTS/WSCF/classes/com/arjuna/mwlabs/wscf/model/twophase/arjunacore/ParticipantRecord.java
===================================================================
--- labs/jbosstm/trunk/XTS/WSCF/classes/com/arjuna/mwlabs/wscf/model/twophase/arjunacore/ParticipantRecord.java 2008-03-27 14:49:34 UTC (rev 19264)
+++ labs/jbosstm/trunk/XTS/WSCF/classes/com/arjuna/mwlabs/wscf/model/twophase/arjunacore/ParticipantRecord.java 2008-03-27 15:54:55 UTC (rev 19265)
@@ -46,6 +46,7 @@
import com.arjuna.mw.wsas.exceptions.*;
import com.arjuna.mw.wscf.exceptions.*;
+import com.arjuna.webservices.util.ClassLoaderHelper;
import java.io.PrintWriter;
@@ -628,7 +629,8 @@
try
{
String resourcehandleImplClassName = os.unpackString();
- _resourceHandle = (Participant)Class.forName(resourcehandleImplClassName).newInstance();
+ Class clazz = ClassLoaderHelper.forName(ParticipantRecord.class, resourcehandleImplClassName);
+ _resourceHandle = (Participant)clazz.newInstance();
result = _resourceHandle.restore_state(os);
Modified: labs/jbosstm/trunk/XTS/sar/build.xml
===================================================================
--- labs/jbosstm/trunk/XTS/sar/build.xml 2008-03-27 14:49:34 UTC (rev 19264)
+++ labs/jbosstm/trunk/XTS/sar/build.xml 2008-03-27 15:54:55 UTC (rev 19265)
@@ -60,6 +60,10 @@
<property name="build.dir" value="build"/>
<property name="build.webinf.dir" value="${build.dir}/WEB-INF"/>
+ <!-- enable debugging of XTS service code -->
+
+ <property name="javac.debug" value="on"/>
+
<target name="init">
<delete dir="${build.dir}"/>
<mkdir dir="${build.dir}"/>
@@ -80,7 +84,7 @@
jboss-system-jmx.jar.
-->
<!--
- <javac srcdir="src" destdir="${build.dir}">
+ <javac srcdir="src" destdir="${build.dir}" debug="${javac.debug}">
<classpath>
<pathelement location="${jbossas.home}/lib/jboss-common.jar"/>
<pathelement location="${jbossas.home}/lib/jboss-system.jar"/>
@@ -90,7 +94,7 @@
</classpath>
</javac>
-->
- <javac srcdir="src" destdir="${build.dir}">
+ <javac srcdir="src" destdir="${build.dir}" debug="${javac.debug}">
<classpath>
<pathelement location="${jbossas.home}/client/jbossall-client.jar"/>
<pathelement location="${jbossas.home}/lib/jboss-system-jmx.jar"/>
Modified: labs/jbosstm/trunk/XTS/sar/src/org/jboss/transactions/XTSService.java
===================================================================
--- labs/jbosstm/trunk/XTS/sar/src/org/jboss/transactions/XTSService.java 2008-03-27 14:49:34 UTC (rev 19264)
+++ labs/jbosstm/trunk/XTS/sar/src/org/jboss/transactions/XTSService.java 2008-03-27 15:54:55 UTC (rev 19265)
@@ -148,6 +148,11 @@
WSTXInitialisation(); // com.arjuna.mw.wst.deploy.WSTXInitialisation : Initialise WSTX
acCoordinatorRecoveryModule = new ACCoordinatorRecoveryModule();
+
+ // ensure Implementations are installed into the inventory before we register the module
+
+ acCoordinatorRecoveryModule.install();
+
// we assume the tx manager has started, hence initializing the recovery manager.
// to guarantee this our mbean should depend on the tx mgr mbean. (but does that g/tee start or just load?)
RecoveryManager.manager().addModule(acCoordinatorRecoveryModule);
@@ -159,7 +164,10 @@
getLog().info("JBossTS XTS Transaction Service - stopping");
if (acCoordinatorRecoveryModule != null) {
- RecoveryManager.manager().removeModule(acCoordinatorRecoveryModule);
+ // remove the module, making sure no any scan which might be using it has completed
+ RecoveryManager.manager().removeModule(acCoordinatorRecoveryModule, true);
+ // ok, now it is safe to get the recovery manager to uninstall its Implementations from the inventory
+ acCoordinatorRecoveryModule.uninstall();
}
TaskManager.getManager().shutdown() ; // com.arjuna.services.framework.admin.TaskManagerInitialisation
Modified: labs/jbosstm/trunk/XTS/sar/src/org/jboss/transactions/xts/recovery/ACCoordinatorRecoveryModule.java
===================================================================
--- labs/jbosstm/trunk/XTS/sar/src/org/jboss/transactions/xts/recovery/ACCoordinatorRecoveryModule.java 2008-03-27 14:49:34 UTC (rev 19264)
+++ labs/jbosstm/trunk/XTS/sar/src/org/jboss/transactions/xts/recovery/ACCoordinatorRecoveryModule.java 2008-03-27 15:54:55 UTC (rev 19265)
@@ -74,11 +74,27 @@
}
_transactionStatusConnectionMgr = new TransactionStatusConnectionManager() ;
+ }
- Implementations.initialise();
+ /**
+ * called by the service startup code before the recovery module is added to the recovery managers
+ * module list
+ */
+ public void install()
+ {
+ Implementations.install();
}
/**
+ * called by the service shutdown code after the recovery module is removed from the recovery managers
+ * module list in order to allow the implementations list to be purged of this module's implementations
+ */
+ public void uninstall()
+ {
+ Implementations.uninstall();
+ }
+
+ /**
* This is called periodically by the RecoveryManager
*/
public void periodicWorkFirstPass()
Modified: labs/jbosstm/trunk/XTS/sar/src/org/jboss/transactions/xts/recovery/Implementations.java
===================================================================
--- labs/jbosstm/trunk/XTS/sar/src/org/jboss/transactions/xts/recovery/Implementations.java 2008-03-27 14:49:34 UTC (rev 19264)
+++ labs/jbosstm/trunk/XTS/sar/src/org/jboss/transactions/xts/recovery/Implementations.java 2008-03-27 15:54:55 UTC (rev 19265)
@@ -33,31 +33,25 @@
*/
public class Implementations {
- public static synchronized boolean added ()
- {
- return _added;
- }
+ static ParticipantRecordSetup _inventoryItem = null;
- public static synchronized void initialise ()
+ public static synchronized void install ()
{
- if (!_added)
- {
+ if (_inventoryItem == null) {
+ _inventoryItem = new ParticipantRecordSetup();
// WS-AT Participant records.
- Inventory.inventory().addToList(new ParticipantRecordSetup());
-
- _added = true;
+ Inventory.inventory().addToList(_inventoryItem);
}
}
- private Implementations ()
+ public static synchronized void uninstall()
{
+ if (_inventoryItem != null) {
+ Inventory.inventory().removeFromList(_inventoryItem.className());
+ }
}
- private static boolean _added = false;
-
- static
+ private Implementations ()
{
- initialise();
}
-
}
More information about the jboss-svn-commits
mailing list