You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by ti...@apache.org on 2016/09/21 08:14:21 UTC

svn commit: r1761694 - in /aries/trunk/tx-control/tx-control-service-xa/src: main/java/org/apache/aries/tx/control/service/xa/impl/ test/java/org/apache/aries/tx/control/service/xa/impl/

Author: timothyjward
Date: Wed Sep 21 08:14:21 2016
New Revision: 1761694

URL: http://svn.apache.org/viewvc?rev=1761694&view=rev
Log:
ARIES-1616 Force the transaction log to close when Transaction Control shuts down

Modified:
    aries/trunk/tx-control/tx-control-service-xa/src/main/java/org/apache/aries/tx/control/service/xa/impl/Activator.java
    aries/trunk/tx-control/tx-control-service-xa/src/main/java/org/apache/aries/tx/control/service/xa/impl/TransactionControlImpl.java
    aries/trunk/tx-control/tx-control-service-xa/src/test/java/org/apache/aries/tx/control/service/xa/impl/TransactionLogTest.java

Modified: aries/trunk/tx-control/tx-control-service-xa/src/main/java/org/apache/aries/tx/control/service/xa/impl/Activator.java
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-service-xa/src/main/java/org/apache/aries/tx/control/service/xa/impl/Activator.java?rev=1761694&r1=1761693&r2=1761694&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-service-xa/src/main/java/org/apache/aries/tx/control/service/xa/impl/Activator.java (original)
+++ aries/trunk/tx-control/tx-control-service-xa/src/main/java/org/apache/aries/tx/control/service/xa/impl/Activator.java Wed Sep 21 08:14:21 2016
@@ -143,7 +143,7 @@ public class Activator implements Bundle
 							}
 							boolean cleanUp = true;
 							synchronized (Activator.this) {
-								if(configuration == newConfig) {
+								if(configuration == newConfig && open) {
 									txControlImpl = impl;
 									txControlReg = newReg;
 									cleanUp = false;

Modified: aries/trunk/tx-control/tx-control-service-xa/src/main/java/org/apache/aries/tx/control/service/xa/impl/TransactionControlImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-service-xa/src/main/java/org/apache/aries/tx/control/service/xa/impl/TransactionControlImpl.java?rev=1761694&r1=1761693&r2=1761694&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-service-xa/src/main/java/org/apache/aries/tx/control/service/xa/impl/TransactionControlImpl.java (original)
+++ aries/trunk/tx-control/tx-control-service-xa/src/main/java/org/apache/aries/tx/control/service/xa/impl/TransactionControlImpl.java Wed Sep 21 08:14:21 2016
@@ -24,6 +24,7 @@ import static org.apache.aries.tx.contro
 import static org.apache.aries.tx.control.service.xa.impl.LocalResourceSupport.ENFORCE_SINGLE;
 
 import java.io.File;
+import java.lang.reflect.Field;
 import java.util.Dictionary;
 import java.util.HashMap;
 import java.util.Hashtable;
@@ -202,16 +203,54 @@ public class TransactionControlImpl exte
 	
 	@Override
 	public void close() {
-		super.close();
-		if(recoverableResources != null) {
-			recoverableResources.close();
-		}
-		if(log != null) {
-			try {
-				log.doStop();
-			} catch (Exception e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
+		try {
+			super.close();
+			if(recoverableResources != null) {
+				recoverableResources.close();
+			}
+		} finally {
+			if(log != null) {
+				try {
+					log.doStop();
+				} catch (Exception e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+				// The HOWL log does not reliably close the FlushManager
+				// and the project hasn't been updated in ten years...
+				// Do some horrible reflection to force it closed so that
+				// we don't leak classloaders and memory.
+				// Note that the thread is daemon, so it won't stop shutdown
+				try {
+					Field f = HOWLLog.class.getDeclaredField("logger");
+					f.setAccessible(true);
+					org.objectweb.howl.log.Logger howlLogger = (org.objectweb.howl.log.Logger) f.get(log);
+					
+					f = org.objectweb.howl.log.Logger.class.getDeclaredField("bmgr");
+					f.setAccessible(true);
+					Object logBufferManager = f.get(howlLogger);
+					
+					f = logBufferManager.getClass().getDeclaredField("flushManager");
+					f.setAccessible(true);
+					Thread flushThread = (Thread) f.get(logBufferManager);
+					
+					if(flushThread.isAlive()) {
+						// Briefly Join this thread in case it is going to stop properly.
+						// Pick the shorter of 250 milliseconds or twice the flush interval.
+						int toWait = Math.min(250, 2* log.getFlushSleepTimeMilliseconds());
+						flushThread.join(toWait);
+
+						if(flushThread.isAlive()) {
+							// Still alive after waiting, time to pull the trigger ourselves
+							flushThread.interrupt();
+							
+							// Let the thread react to interruption
+							flushThread.join(toWait);
+						}
+					}
+				} catch (Exception e) {
+					logger.error("An error ocurred while trying to close the HOWL flush thread.", e);
+				}
 			}
 		}
 	}

Modified: aries/trunk/tx-control/tx-control-service-xa/src/test/java/org/apache/aries/tx/control/service/xa/impl/TransactionLogTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/tx-control/tx-control-service-xa/src/test/java/org/apache/aries/tx/control/service/xa/impl/TransactionLogTest.java?rev=1761694&r1=1761693&r2=1761694&view=diff
==============================================================================
--- aries/trunk/tx-control/tx-control-service-xa/src/test/java/org/apache/aries/tx/control/service/xa/impl/TransactionLogTest.java (original)
+++ aries/trunk/tx-control/tx-control-service-xa/src/test/java/org/apache/aries/tx/control/service/xa/impl/TransactionLogTest.java Wed Sep 21 08:14:21 2016
@@ -25,6 +25,7 @@ import static org.junit.Assert.assertTru
 import static org.osgi.service.transaction.control.TransactionStatus.ROLLED_BACK;
 
 import java.io.File;
+import java.lang.reflect.Field;
 import java.sql.Connection;
 import java.sql.ResultSet;
 import java.sql.SQLException;
@@ -37,6 +38,7 @@ import java.util.function.BiConsumer;
 import javax.sql.XAConnection;
 import javax.transaction.xa.XAResource;
 
+import org.apache.geronimo.transaction.log.HOWLLog;
 import org.h2.jdbcx.JdbcDataSource;
 import org.h2.tools.Server;
 import org.junit.After;
@@ -106,8 +108,10 @@ public class TransactionLogTest {
 	}
 	
 	@After
-	public void destroy() {
+	public void destroy() throws Exception {
 		txControl.close();
+		
+		checkLogClosed(txControl);
 		try (Connection conn = dataSource.getConnection()) {
 			conn.createStatement().execute("shutdown immediately");
 		} catch (SQLException e) {
@@ -118,6 +122,37 @@ public class TransactionLogTest {
 		delete(new File("target/recovery-test"));
 	}
 
+	private void checkLogClosed(TransactionControlImpl toCheck) throws Exception {
+		
+		Field f = TransactionControlImpl.class.getDeclaredField("log");
+		f.setAccessible(true);
+		HOWLLog log = (HOWLLog) f.get(toCheck);
+		
+		f = HOWLLog.class.getDeclaredField("logger");
+		f.setAccessible(true);
+		org.objectweb.howl.log.Logger howlLogger = (org.objectweb.howl.log.Logger) f.get(log);
+		
+		f = org.objectweb.howl.log.Logger.class.getDeclaredField("bmgr");
+		f.setAccessible(true);
+		Object logBufferManager = f.get(howlLogger);
+		
+		f = logBufferManager.getClass().getDeclaredField("flushManager");
+		f.setAccessible(true);
+		Thread flushThread = (Thread) f.get(logBufferManager);
+		
+		assertFalse(flushThread.isAlive());
+		
+		f = org.objectweb.howl.log.Logger.class.getDeclaredField("lfmgr");
+		f.setAccessible(true);
+		Object logFileManager = f.get(howlLogger);
+		
+		f = logFileManager.getClass().getDeclaredField("eventManagerThread");
+		f.setAccessible(true);
+		Thread eventManagerThread = (Thread) f.get(logFileManager);
+		
+		assertFalse(eventManagerThread.isAlive());
+	}
+
 	private void delete(File file) {
 		if(file.isDirectory()) {
 			for(File f : file.listFiles()) {