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()) {