You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by jg...@apache.org on 2015/07/30 16:53:19 UTC
[08/17] tomee git commit: Revert "TOMEE-1615 avoid to create N
connections for the same datasource in the same transaction - very good catch
from Jon. Also using TransactionSynchronizationRegistry instead of a static
Map"
Revert "TOMEE-1615 avoid to create N connections for the same datasource in the same transaction - very good catch from Jon. Also using TransactionSynchronizationRegistry instead of a static Map"
This reverts commit c390227be8852a4713125a33d90d09dff317b93e.
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/1922c13c
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/1922c13c
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/1922c13c
Branch: refs/heads/tomee-1.7.x
Commit: 1922c13cafbfbfa3f8faafe11741cbf4ed342eb2
Parents: 01bb65b
Author: Jonathan Gallimore <jo...@jrg.me.uk>
Authored: Thu Jul 30 13:46:42 2015 +0100
Committer: Jonathan Gallimore <jo...@jrg.me.uk>
Committed: Thu Jul 30 13:46:42 2015 +0100
----------------------------------------------------------------------
.../openejb/assembler/classic/Assembler.java | 5 +
.../persistence/PersistenceUnitInfoImpl.java | 8 +-
.../jdbc/FlushableDataSourceHandler.java | 7 +-
.../resource/jdbc/SimpleDataSourceCreator.java | 6 +-
.../jdbc/dbcp/DbcpDataSourceCreator.java | 6 +-
.../managed/JTADataSourceWrapperFactory.java | 5 +-
.../jdbc/managed/local/ManagedConnection.java | 217 ++++-----
.../jdbc/managed/local/ManagedDataSource.java | 44 +-
.../managed/xa/CommonDataSourceAdapter.java | 9 -
.../jdbc/managed/xa/DataSourceXADataSource.java | 5 +-
.../jdbc/managed/xa/ManagedXAConnection.java | 21 +-
.../jdbc/managed/xa/ManagedXADataSource.java | 26 +-
.../jdbc/pool/PoolDataSourceCreator.java | 18 +-
.../jdbc/ManagedConnectionBehaviorTest.java | 461 -------------------
.../resource/jdbc/ManagedDataSourceTest.java | 27 +-
.../MultiThreadedManagedDataSourceTest.java | 26 +-
.../openejb/bonecp/BoneCPDataSourceCreator.java | 4 +-
.../BoneCPPooledDataSourceFromPoolTest.java | 30 +-
.../bonecp/BoneCPPooledDataSourceTest.java | 27 +-
.../org/apache/openejb/bonecp/XABoneCPTest.java | 4 +-
.../jdbc/TomcatDataSourceFromPoolTest.java | 27 +-
.../org/apache/tomee/jdbc/TomcatPoolTest.java | 27 +-
22 files changed, 285 insertions(+), 725 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/1922c13c/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
index ed3b18d..e5c1899 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
@@ -1711,6 +1711,11 @@ public class Assembler extends AssemblerTool implements org.apache.openejb.spi.A
} catch (final Throwable t) {
//Ignore
}
+
+ if (object instanceof ManagedDataSource) {
+ ((ManagedDataSource) object).clean();
+ }
+
} else if (object instanceof ConnectorReference) {
final ConnectorReference cr = (ConnectorReference) object;
try {
http://git-wip-us.apache.org/repos/asf/tomee/blob/1922c13c/container/openejb-core/src/main/java/org/apache/openejb/persistence/PersistenceUnitInfoImpl.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/persistence/PersistenceUnitInfoImpl.java b/container/openejb-core/src/main/java/org/apache/openejb/persistence/PersistenceUnitInfoImpl.java
index 3ed9aff..c849ad6 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/persistence/PersistenceUnitInfoImpl.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/persistence/PersistenceUnitInfoImpl.java
@@ -19,7 +19,6 @@ package org.apache.openejb.persistence;
import org.apache.openejb.OpenEJB;
-import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.resource.jdbc.managed.xa.DataSourceXADataSource;
import org.apache.openejb.util.URLs;
import org.apache.openejb.util.classloader.URLClassLoaderFirst;
@@ -32,7 +31,6 @@ import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.sql.CommonDataSource;
import javax.sql.DataSource;
import javax.sql.XADataSource;
-import javax.transaction.TransactionSynchronizationRegistry;
import java.io.File;
import java.io.IOException;
import java.lang.instrument.ClassFileTransformer;
@@ -196,8 +194,7 @@ public class PersistenceUnitInfoImpl implements PersistenceUnitInfo {
public void setJtaDataSource(final CommonDataSource jtaDataSource) {
if (XADataSource.class.isInstance(jtaDataSource)) {
- this.jtaDataSource = new DataSourceXADataSource(
- jtaDataSource, OpenEJB.getTransactionManager(), SystemInstance.get().getComponent(TransactionSynchronizationRegistry.class));
+ this.jtaDataSource = new DataSourceXADataSource(jtaDataSource, OpenEJB.getTransactionManager());
} else {
this.jtaDataSource = DataSource.class.cast(jtaDataSource);
}
@@ -209,8 +206,7 @@ public class PersistenceUnitInfoImpl implements PersistenceUnitInfo {
public void setNonJtaDataSource(final CommonDataSource nonJtaDataSource) {
if (XADataSource.class.isInstance(nonJtaDataSource)) {
- this.nonJtaDataSource = new DataSourceXADataSource(
- nonJtaDataSource, OpenEJB.getTransactionManager(), SystemInstance.get().getComponent(TransactionSynchronizationRegistry.class));
+ this.nonJtaDataSource = new DataSourceXADataSource(nonJtaDataSource, OpenEJB.getTransactionManager());
} else {
this.nonJtaDataSource = DataSource.class.cast(nonJtaDataSource);
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/1922c13c/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/FlushableDataSourceHandler.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/FlushableDataSourceHandler.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/FlushableDataSourceHandler.java
index 316565b..79c9510 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/FlushableDataSourceHandler.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/FlushableDataSourceHandler.java
@@ -16,10 +16,12 @@
*/
package org.apache.openejb.resource.jdbc;
+import org.apache.openejb.resource.jdbc.managed.local.ManagedDataSource;
import org.apache.openejb.util.Duration;
import org.apache.openejb.util.LogCategory;
import org.apache.openejb.util.Logger;
+import javax.sql.CommonDataSource;
import java.io.Flushable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
@@ -27,7 +29,6 @@ import java.lang.reflect.Method;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
-import javax.sql.CommonDataSource;
public class FlushableDataSourceHandler implements InvocationHandler {
private static final Logger LOGGER = Logger.getInstance(LogCategory.OPENEJB, FlushableDataSourceHandler.class);
@@ -57,6 +58,10 @@ public class FlushableDataSourceHandler implements InvocationHandler {
} catch (final Throwable t) {
//Ignore
}
+
+ if (ManagedDataSource.class.isInstance(old)) {
+ ManagedDataSource.class.cast(old).clean();
+ }
}
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/1922c13c/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/SimpleDataSourceCreator.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/SimpleDataSourceCreator.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/SimpleDataSourceCreator.java
index c16787b..47b774c 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/SimpleDataSourceCreator.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/SimpleDataSourceCreator.java
@@ -18,7 +18,6 @@
package org.apache.openejb.resource.jdbc;
import org.apache.openejb.OpenEJB;
-import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.resource.XAResourceWrapper;
import org.apache.openejb.resource.jdbc.managed.local.ManagedDataSource;
import org.apache.openejb.resource.jdbc.managed.xa.ManagedXADataSource;
@@ -29,7 +28,6 @@ import javax.sql.CommonDataSource;
import javax.sql.DataSource;
import javax.sql.XADataSource;
import javax.transaction.TransactionManager;
-import javax.transaction.TransactionSynchronizationRegistry;
import java.util.Properties;
public class SimpleDataSourceCreator implements DataSourceCreator {
@@ -37,9 +35,9 @@ public class SimpleDataSourceCreator implements DataSourceCreator {
public DataSource managed(final String name, final CommonDataSource ds) {
final TransactionManager transactionManager = OpenEJB.getTransactionManager();
if (XADataSource.class.isInstance(ds)) {
- return new ManagedXADataSource(XADataSource.class.cast(ds), transactionManager, SystemInstance.get().getComponent(TransactionSynchronizationRegistry.class));
+ return new ManagedXADataSource(XADataSource.class.cast(ds), transactionManager);
}
- return new ManagedDataSource(DataSource.class.cast(ds), transactionManager, SystemInstance.get().getComponent(TransactionSynchronizationRegistry.class));
+ return new ManagedDataSource(DataSource.class.cast(ds), transactionManager);
}
@Override
http://git-wip-us.apache.org/repos/asf/tomee/blob/1922c13c/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/dbcp/DbcpDataSourceCreator.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/dbcp/DbcpDataSourceCreator.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/dbcp/DbcpDataSourceCreator.java
index bc0ca31..7306655 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/dbcp/DbcpDataSourceCreator.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/dbcp/DbcpDataSourceCreator.java
@@ -18,7 +18,6 @@
package org.apache.openejb.resource.jdbc.dbcp;
import org.apache.openejb.OpenEJB;
-import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.resource.jdbc.managed.local.ManagedDataSource;
import org.apache.openejb.resource.jdbc.managed.xa.ManagedXADataSource;
import org.apache.openejb.resource.jdbc.pool.PoolDataSourceCreator;
@@ -28,7 +27,6 @@ import javax.sql.CommonDataSource;
import javax.sql.DataSource;
import javax.sql.XADataSource;
import javax.transaction.TransactionManager;
-import javax.transaction.TransactionSynchronizationRegistry;
import java.util.Properties;
// just a sample showing how to implement a datasourcecreator
@@ -43,9 +41,9 @@ public class DbcpDataSourceCreator extends PoolDataSourceCreator {
public DataSource managed(final String name, final CommonDataSource ds) {
final TransactionManager transactionManager = OpenEJB.getTransactionManager();
if (ds instanceof XADataSource) {
- return new ManagedXADataSource(ds, transactionManager, SystemInstance.get().getComponent(TransactionSynchronizationRegistry.class));
+ return new ManagedXADataSource(ds, transactionManager);
}
- return new ManagedDataSource(DataSource.class.cast(ds), transactionManager, SystemInstance.get().getComponent(TransactionSynchronizationRegistry.class));
+ return new ManagedDataSource(DataSource.class.cast(ds), transactionManager);
}
@Override
http://git-wip-us.apache.org/repos/asf/tomee/blob/1922c13c/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/JTADataSourceWrapperFactory.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/JTADataSourceWrapperFactory.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/JTADataSourceWrapperFactory.java
index cfdf927..48e29fc 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/JTADataSourceWrapperFactory.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/JTADataSourceWrapperFactory.java
@@ -30,7 +30,6 @@ import javax.sql.CommonDataSource;
import javax.sql.DataSource;
import javax.sql.XADataSource;
import javax.transaction.TransactionManager;
-import javax.transaction.TransactionSynchronizationRegistry;
public class JTADataSourceWrapperFactory {
private String delegate = "datasource";
@@ -42,9 +41,9 @@ public class JTADataSourceWrapperFactory {
CommonDataSource cds = findDelegate();
if (cds instanceof XADataSource) {
- cds = new ManagedXADataSource(cds, transactionManager, SystemInstance.get().getComponent(TransactionSynchronizationRegistry.class));
+ cds = new ManagedXADataSource(cds, transactionManager);
} else {
- cds = new ManagedDataSource(DataSource.class.cast(cds), transactionManager, SystemInstance.get().getComponent(TransactionSynchronizationRegistry.class));
+ cds = new ManagedDataSource(DataSource.class.cast(cds), transactionManager);
}
if (logSql) {
http://git-wip-us.apache.org/repos/asf/tomee/blob/1922c13c/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/local/ManagedConnection.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/local/ManagedConnection.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/local/ManagedConnection.java
index 02bb552..25e1727 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/local/ManagedConnection.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/local/ManagedConnection.java
@@ -17,52 +17,48 @@
package org.apache.openejb.resource.jdbc.managed.local;
+import org.apache.openejb.OpenEJB;
import org.apache.openejb.util.LogCategory;
import org.apache.openejb.util.Logger;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.sql.Wrapper;
import javax.sql.CommonDataSource;
-import javax.sql.DataSource;
-import javax.sql.XAConnection;
-import javax.sql.XADataSource;
import javax.transaction.RollbackException;
import javax.transaction.Status;
import javax.transaction.Synchronization;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
-import javax.transaction.TransactionSynchronizationRegistry;
import javax.transaction.xa.XAResource;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
public class ManagedConnection implements InvocationHandler {
+ private static final Logger LOGGER = Logger.getInstance(LogCategory.OPENEJB_RESOURCE_JDBC, ManagedConnection.class);
+
+ private static final Map<Integer, Map<Transaction, Connection>> CONNECTION_BY_TX_BY_DS = new ConcurrentHashMap<Integer, Map<Transaction, Connection>>();
+
private final TransactionManager transactionManager;
- private final Key key;
- private final TransactionSynchronizationRegistry registry;
- protected XAResource xaResource;
+ private final LocalXAResource xaResource;
protected Connection delegate;
- protected XAConnection xaConnection;
private Transaction currentTransaction;
private boolean closed;
- public ManagedConnection(final CommonDataSource ds,
- final TransactionManager txMgr,
- final TransactionSynchronizationRegistry txRegistry,
- final String user, final String password) {
+ private final Map<Transaction, Connection> connectionByTx;
+
+ public ManagedConnection(final CommonDataSource ds, final Connection connection, final TransactionManager txMgr) {
+ delegate = connection;
transactionManager = txMgr;
- registry = txRegistry;
closed = false;
- key = new Key(ds, user, password);
+ xaResource = new LocalXAResource(delegate);
+ connectionByTx = CONNECTION_BY_TX_BY_DS.get(ds.hashCode());
}
public XAResource getXAResource() throws SQLException {
- if (xaResource == null) {
- newConnection();
- }
return xaResource;
}
@@ -74,110 +70,80 @@ public class ManagedConnection implements InvocationHandler {
return "ManagedConnection{" + delegate + "}";
}
if ("hashCode".equals(mtdName)) {
- return hashCode();
+ return delegate.hashCode();
}
if ("equals".equals(mtdName)) {
- return args[0] == this || (delegate != null && delegate.equals(args[0]));
- }
-
- // allow to get delegate if needed by the underlying program
- if (Wrapper.class == method.getDeclaringClass() && args.length == 1 && Connection.class == args[0]) {
- if ("isWrapperFor".equals(mtdName)) {
- return true;
- }
- if ("unwrap".equals(mtdName)) {
- return delegate;
- }
+ return delegate.equals(args[0]);
}
// here the real logic starts
try {
final Transaction transaction = transactionManager.getTransaction();
- // shouldn't be used without a transaction but if so just delegate to the actual connection
- if (transaction == null) {
- if (delegate == null) {
- newConnection();
- }
+ if (transaction == null) { // shouldn't be possible
return invoke(method, delegate, args);
}
// if we have a tx check it is the same this connection is linked to
- if (currentTransaction != null && isUnderTransaction(currentTransaction.getStatus())) {
- if (!currentTransaction.equals(transaction)) {
- throw new SQLException("Connection can not be used while enlisted in another transaction");
+ if (currentTransaction != null) {
+ if (isUnderTransaction(currentTransaction.getStatus())) {
+ if (!currentTransaction.equals(transaction)) {
+ throw new SQLException("Connection can not be used while enlisted in another transaction");
+ }
+ return invokeUnderTransaction(delegate, method, args);
+ } else {
+ close(delegate);
}
- return invokeUnderTransaction(delegate, method, args);
}
- // get the already bound connection to the current transaction or enlist this one in the tx
- if (isUnderTransaction(transaction.getStatus())) {
- Connection connection = Connection.class.cast(registry.getResource(key));
- if (connection == null && delegate == null) {
- newConnection();
- connection = delegate;
-
- registry.putResource(transaction, delegate);
- currentTransaction = transaction;
- try {
- transaction.enlistResource(getXAResource());
- } catch (final RollbackException ignored) {
- // no-op
- } catch (final SystemException e) {
- throw new SQLException("Unable to enlist connection the transaction", e);
- }
-
- transaction.registerSynchronization(new ClosingSynchronization(delegate));
+ // get the already bound connection to the current transaction
+ // or enlist this one in the tx
+ final int status = transaction.getStatus();
+ if (isUnderTransaction(status)) {
+ final Connection connection = connectionByTx.get(transaction);
+ if (connection != delegate) {
+ if (connection != null) { // use already existing one
+ delegate.close(); // return to pool
+ delegate = connection;
+ } else {
+ connectionByTx.put(transaction, delegate);
+ currentTransaction = transaction;
+ try {
+ transaction.enlistResource(getXAResource());
+ } catch (final RollbackException ignored) {
+ // no-op
+ } catch (final SystemException e) {
+ throw new SQLException("Unable to enlist connection the transaction", e);
+ }
- try {
- setAutoCommit(false);
- } catch (final SQLException xae) { // we are alreay in a transaction so this can't be called from a user perspective - some XA DataSource prevents it in their code
- final String message = "Can't set auto commit to false cause the XA datasource doesn't support it, this is likely an issue";
- final Logger logger = Logger.getInstance(LogCategory.OPENEJB_RESOURCE_JDBC, ManagedConnection.class)
- if (logger.isDebugEnabled()) { // we don't want to print the exception by default
- logger.warning(message, xae);
- } else {
- logger.warning(message);
+ transaction.registerSynchronization(new ClosingSynchronization(delegate, connectionByTx));
+
+ try {
+ setAutoCommit(false);
+ } catch (final SQLException xae) { // we are already in a transaction so this can't be called from a user perspective - some XA DataSource prevents it in their code
+ final String message = "Can't set auto commit to false cause the XA datasource doesn't support it, this is likely an issue";
+ if (LOGGER.isDebugEnabled()) { // we don't want to print the exception by default
+ LOGGER.warning(message, xae);
+ } else {
+ LOGGER.warning(message);
+ }
}
}
- } else if (delegate == null) { // shouldn't happen
- delegate = connection;
}
- return invokeUnderTransaction(connection, method, args);
+ return invokeUnderTransaction(delegate, method, args);
}
- // we shouldn't come here, tempted to just throw an exception
- if (delegate == null) {
- newConnection();
- }
return invoke(method, delegate, args);
} catch (final InvocationTargetException ite) {
throw ite.getTargetException();
}
}
- protected Object newConnection() throws SQLException {
- final Object connection = DataSource.class.isInstance(key.ds) ?
- (key.user == null ? DataSource.class.cast(key.ds).getConnection() : DataSource.class.cast(key.ds).getConnection(key.user, key.pwd)) :
- (key.user == null ? XADataSource.class.cast(key.ds).getXAConnection() : XADataSource.class.cast(key.ds).getXAConnection(key.user, key.pwd));
- if (XAConnection.class.isInstance(connection)) {
- xaConnection = XAConnection.class.cast(connection);
- delegate = xaConnection.getConnection();
- xaResource = xaConnection.getXAResource();
- } else {
- delegate = Connection.class.cast(connection);
- xaResource = new LocalXAResource(delegate);
- }
- return connection;
- }
-
protected void setAutoCommit(final boolean value) throws SQLException {
- if (delegate == null) {
- newConnection();
- }
delegate.setAutoCommit(value);
}
+
private static Object invoke(final Method method, final Connection delegate, final Object[] args) throws Throwable {
try {
return method.invoke(delegate, args);
@@ -229,11 +195,24 @@ public class ManagedConnection implements InvocationHandler {
}
}
+ public static void pushDataSource(final CommonDataSource ds) {
+ CONNECTION_BY_TX_BY_DS.put(ds.hashCode(), new ConcurrentHashMap<Transaction, Connection>());
+ }
+
+ public static void cleanDataSource(final CommonDataSource ds) {
+ final Map<Transaction, Connection> map = CONNECTION_BY_TX_BY_DS.remove(ds.hashCode());
+ if (map != null) {
+ map.clear();
+ }
+ }
+
private static class ClosingSynchronization implements Synchronization {
private final Connection connection;
+ private final Map<Transaction, Connection> mapToCleanup;
- public ClosingSynchronization(final Connection delegate) {
- this.connection = delegate;
+ public ClosingSynchronization(final Connection delegate, final Map<Transaction, Connection> connByTx) {
+ connection = delegate;
+ mapToCleanup = connByTx;
}
@Override
@@ -244,44 +223,12 @@ public class ManagedConnection implements InvocationHandler {
@Override
public void afterCompletion(final int status) {
close(connection);
- }
- }
-
- private static class Key {
- private final CommonDataSource ds;
- private final String user;
- private final String pwd;
- private final int hash;
-
- private Key(final CommonDataSource ds, final String user, final String pwd) {
- this.ds = ds;
- this.user = user;
- this.pwd = pwd;
-
- int result = ds.hashCode();
- result = 31 * result + (user != null ? user.hashCode() : 0);
- result = 31 * result + (pwd != null ? pwd.hashCode() : 0);
- hash = result;
- }
-
- @Override
- public boolean equals(final Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
+ try {
+ final Transaction tx = OpenEJB.getTransactionManager().getTransaction();
+ mapToCleanup.remove(tx);
+ } catch (final SystemException ignored) {
+ // no-op
}
-
- Key key = Key.class.cast(o);
- return (ds == key.ds || ds.equals(key.ds)) &&
- !(user != null ? !user.equals(key.user) : key.user != null) &&
- !(pwd != null ? !pwd.equals(key.pwd) : key.pwd != null);
- }
-
- @Override
- public int hashCode() {
- return hash;
}
}
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/1922c13c/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/local/ManagedDataSource.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/local/ManagedDataSource.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/local/ManagedDataSource.java
index 0c10b80..0c074f9 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/local/ManagedDataSource.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/local/ManagedDataSource.java
@@ -17,45 +17,44 @@
package org.apache.openejb.resource.jdbc.managed.local;
-import java.io.ObjectStreamException;
+import org.apache.openejb.util.reflection.Reflections;
+
+import javax.sql.CommonDataSource;
+import javax.sql.DataSource;
+import javax.transaction.TransactionManager;
import java.io.PrintWriter;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;
-import javax.sql.CommonDataSource;
-import javax.sql.DataSource;
-import javax.transaction.TransactionManager;
-import javax.transaction.TransactionSynchronizationRegistry;
public class ManagedDataSource implements DataSource {
private static final Class<?>[] CONNECTION_CLASS = new Class<?>[]{Connection.class};
- protected final CommonDataSource delegate;
+ protected final DataSource delegate;
protected final TransactionManager transactionManager;
- protected final TransactionSynchronizationRegistry registry;
protected final int hashCode;
- protected ManagedDataSource(final CommonDataSource ds, final TransactionManager txMgr, final TransactionSynchronizationRegistry txRegistry, final int hc) {
+ protected ManagedDataSource(final DataSource ds, final TransactionManager txMgr, final int hc) {
delegate = ds;
hashCode = hc;
transactionManager = txMgr;
- registry = txRegistry;
+ ManagedConnection.pushDataSource(this);
}
- public ManagedDataSource(final DataSource ds, final TransactionManager txMgr, final TransactionSynchronizationRegistry txRegistry) {
- this(ds, txMgr, txRegistry, ds.hashCode());
+ public ManagedDataSource(final DataSource ds, final TransactionManager txMgr) {
+ this(ds, txMgr, ds.hashCode());
}
@Override
public Connection getConnection() throws SQLException {
- return managed(null, null);
+ return managed(delegate.getConnection());
}
@Override
public Connection getConnection(final String username, final String password) throws SQLException {
- return managed(username, password);
+ return managed(delegate.getConnection(username, password));
}
@Override
@@ -80,28 +79,31 @@ public class ManagedDataSource implements DataSource {
@Override
public <T> T unwrap(final Class<T> iface) throws SQLException {
- return DataSource.class.isInstance(delegate) ? DataSource.class.cast(delegate).unwrap(iface) : null;
+ return delegate.unwrap(iface);
}
@Override
public boolean isWrapperFor(final Class<?> iface) throws SQLException {
- return DataSource.class.isInstance(delegate) && DataSource.class.cast(delegate).isWrapperFor(iface);
+ return delegate.isWrapperFor(iface);
}
- @Override
+ // @Override JDK7
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
- return delegate.getParentLogger();
+ return (Logger) Reflections.invokeByReflection(delegate, "getParentLogger", new Class<?>[0], null);
}
- private Connection managed(final String u, final String p) {
- return (Connection) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), CONNECTION_CLASS,
- new ManagedConnection(delegate, transactionManager, registry, u, p));
+ private Connection managed(final Connection connection) {
+ return (Connection) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), CONNECTION_CLASS, new ManagedConnection(this, connection, transactionManager));
}
- public CommonDataSource getDelegate() {
+ public DataSource getDelegate() {
return delegate;
}
+ public void clean() {
+ ManagedConnection.cleanDataSource(this);
+ }
+
@Override
public boolean equals(final Object o) {
return CommonDataSource.class.isInstance(o) && hashCode == o.hashCode();
http://git-wip-us.apache.org/repos/asf/tomee/blob/1922c13c/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/xa/CommonDataSourceAdapter.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/xa/CommonDataSourceAdapter.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/xa/CommonDataSourceAdapter.java
index 59e7bb9..bab9a55 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/xa/CommonDataSourceAdapter.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/xa/CommonDataSourceAdapter.java
@@ -36,15 +36,6 @@ public class CommonDataSourceAdapter implements InvocationHandler {
@Override
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
- if (Object.class == method.getDeclaringClass() && "equals".equals(method.getName())) {
- if (delegate == args[0]) {
- return true;
- }
- }
return method.invoke(delegate, args); // we suppose missing methods are not called - it is the case thanks to ManagedXADataSource
}
-
- public CommonDataSource getDelegate() {
- return delegate;
- }
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/1922c13c/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/xa/DataSourceXADataSource.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/xa/DataSourceXADataSource.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/xa/DataSourceXADataSource.java
index ddbcf65..5ec6aea 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/xa/DataSourceXADataSource.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/xa/DataSourceXADataSource.java
@@ -23,15 +23,14 @@ import javax.sql.CommonDataSource;
import javax.sql.XAConnection;
import javax.sql.XADataSource;
import javax.transaction.TransactionManager;
-import javax.transaction.TransactionSynchronizationRegistry;
import java.sql.Connection;
import java.sql.SQLException;
public class DataSourceXADataSource extends ManagedDataSource {
private final XADataSource xaDataSource;
- public DataSourceXADataSource(final CommonDataSource ds, final TransactionManager txMgr, final TransactionSynchronizationRegistry registry) {
- super(CommonDataSourceAdapter.wrap(ds), txMgr, registry, ds.hashCode());
+ public DataSourceXADataSource(final CommonDataSource ds, final TransactionManager txMgr) {
+ super(CommonDataSourceAdapter.wrap(ds), txMgr, ds.hashCode());
xaDataSource = XADataSource.class.cast(ds);
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/1922c13c/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/xa/ManagedXAConnection.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/xa/ManagedXAConnection.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/xa/ManagedXAConnection.java
index c39cb7c..9980793 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/xa/ManagedXAConnection.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/xa/ManagedXAConnection.java
@@ -19,25 +19,24 @@ package org.apache.openejb.resource.jdbc.managed.xa;
import org.apache.openejb.resource.jdbc.managed.local.ManagedConnection;
-import java.sql.SQLException;
-import javax.sql.CommonDataSource;
+import javax.sql.DataSource;
+import javax.sql.XAConnection;
import javax.transaction.TransactionManager;
-import javax.transaction.TransactionSynchronizationRegistry;
import javax.transaction.xa.XAResource;
+import java.sql.Connection;
+import java.sql.SQLException;
public class ManagedXAConnection extends ManagedConnection {
- public ManagedXAConnection(final CommonDataSource ds, final TransactionManager txMgr,
- final TransactionSynchronizationRegistry txRegistry,
- final String user, final String password) throws SQLException {
- super(ds, txMgr, txRegistry, user, password);
+ private final XAConnection xaConnection;
+
+ public ManagedXAConnection(final DataSource ds, final XAConnection xa, final Connection connection, final TransactionManager txMgr) throws SQLException {
+ super(ds, connection, txMgr);
+ this.xaConnection = xa;
}
@Override
public XAResource getXAResource() throws SQLException {
- if (xaResource == null) {
- newConnection();
- }
- return xaResource;
+ return xaConnection.getXAResource();
}
@Override
http://git-wip-us.apache.org/repos/asf/tomee/blob/1922c13c/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/xa/ManagedXADataSource.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/xa/ManagedXADataSource.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/xa/ManagedXADataSource.java
index c2ccced..6e51eb8 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/xa/ManagedXADataSource.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/managed/xa/ManagedXADataSource.java
@@ -19,35 +19,37 @@ package org.apache.openejb.resource.jdbc.managed.xa;
import org.apache.openejb.resource.jdbc.managed.local.ManagedDataSource;
+import javax.sql.CommonDataSource;
+import javax.sql.XAConnection;
+import javax.sql.XADataSource;
+import javax.transaction.TransactionManager;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.SQLException;
-import javax.sql.CommonDataSource;
-import javax.transaction.TransactionManager;
-import javax.transaction.TransactionSynchronizationRegistry;
public class ManagedXADataSource extends ManagedDataSource {
private static final Class<?>[] CONNECTION_CLASS = new Class<?>[]{Connection.class};
- private final TransactionManager txMgr;
+ private final XADataSource xaDataSource;
- public ManagedXADataSource(final CommonDataSource ds, final TransactionManager txMgr, final TransactionSynchronizationRegistry registry) {
- super(ds, txMgr, registry, ds.hashCode());
- this.txMgr = txMgr; // ObjectRecipe and our logic will setTxMgr but we want the original one (wrapper)
+ public ManagedXADataSource(final CommonDataSource ds, final TransactionManager txMgr) {
+ super(CommonDataSourceAdapter.wrap(ds), txMgr, ds.hashCode());
+ xaDataSource = XADataSource.class.cast(ds);
}
@Override
public Connection getConnection() throws SQLException {
- return managedXA(null, null);
+ final XAConnection xaConnection = xaDataSource.getXAConnection();
+ return managedXA(xaConnection, xaConnection.getConnection());
}
@Override
public Connection getConnection(final String username, final String password) throws SQLException {
- return managedXA(username, password);
+ final XAConnection xaConnection = xaDataSource.getXAConnection(username, password);
+ return managedXA(xaConnection, xaConnection.getConnection());
}
- private Connection managedXA(final String u, final String p) throws SQLException {
- return Connection.class.cast(Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), CONNECTION_CLASS,
- new ManagedXAConnection(delegate, txMgr, registry, u, p)));
+ private Connection managedXA(final XAConnection xaConnection, final Connection connection) throws SQLException {
+ return Connection.class.cast(Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), CONNECTION_CLASS, new ManagedXAConnection(delegate, xaConnection, connection, transactionManager)));
}
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/1922c13c/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/pool/PoolDataSourceCreator.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/pool/PoolDataSourceCreator.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/pool/PoolDataSourceCreator.java
index 1e1dba4..f041a88 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/pool/PoolDataSourceCreator.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/pool/PoolDataSourceCreator.java
@@ -18,7 +18,6 @@
package org.apache.openejb.resource.jdbc.pool;
import org.apache.openejb.OpenEJB;
-import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.resource.TransactionManagerWrapper;
import org.apache.openejb.resource.XAResourceWrapper;
import org.apache.openejb.resource.jdbc.managed.local.ManagedDataSource;
@@ -27,15 +26,14 @@ import org.apache.openejb.util.PassthroughFactory;
import org.apache.xbean.recipe.ObjectRecipe;
import org.apache.xbean.recipe.Option;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Properties;
import javax.sql.CommonDataSource;
import javax.sql.DataSource;
import javax.sql.XADataSource;
import javax.transaction.TransactionManager;
-import javax.transaction.TransactionSynchronizationRegistry;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
public abstract class PoolDataSourceCreator implements DataSourceCreator {
protected final Map<Object, ObjectRecipe> recipes = new HashMap<Object, ObjectRecipe>();
@@ -55,9 +53,9 @@ public abstract class PoolDataSourceCreator implements DataSourceCreator {
public DataSource managed(final String name, final CommonDataSource ds) {
final TransactionManager transactionManager = OpenEJB.getTransactionManager();
if (ds instanceof XADataSource) {
- return new ManagedXADataSource(ds, transactionManager, SystemInstance.get().getComponent(TransactionSynchronizationRegistry.class));
+ return new ManagedXADataSource(ds, transactionManager);
}
- return new ManagedDataSource(DataSource.class.cast(ds), transactionManager, SystemInstance.get().getComponent(TransactionSynchronizationRegistry.class));
+ return new ManagedDataSource(DataSource.class.cast(ds), transactionManager);
}
@Override
@@ -65,9 +63,9 @@ public abstract class PoolDataSourceCreator implements DataSourceCreator {
final TransactionManager transactionManager = new TransactionManagerWrapper(OpenEJB.getTransactionManager(), name, xaResourceWrapper);
final CommonDataSource ds = pool(name, driver, properties);
if (ds instanceof XADataSource) {
- return new ManagedXADataSource(ds, transactionManager, SystemInstance.get().getComponent(TransactionSynchronizationRegistry.class));
+ return new ManagedXADataSource(ds, transactionManager);
}
- return new ManagedDataSource(DataSource.class.cast(ds), transactionManager, SystemInstance.get().getComponent(TransactionSynchronizationRegistry.class));
+ return new ManagedDataSource(DataSource.class.cast(ds), transactionManager);
}
@Override
http://git-wip-us.apache.org/repos/asf/tomee/blob/1922c13c/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/ManagedConnectionBehaviorTest.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/ManagedConnectionBehaviorTest.java b/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/ManagedConnectionBehaviorTest.java
deleted file mode 100644
index a5e65cd..0000000
--- a/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/ManagedConnectionBehaviorTest.java
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.openejb.resource.jdbc;
-
-import org.apache.geronimo.transaction.manager.GeronimoTransactionManager;
-import org.apache.openejb.resource.GeronimoTransactionManagerFactory;
-import org.apache.openejb.resource.TransactionManagerWrapper;
-import org.apache.openejb.resource.jdbc.managed.local.ManagedDataSource;
-import org.junit.Test;
-
-import java.io.PrintWriter;
-import java.sql.Array;
-import java.sql.Blob;
-import java.sql.CallableStatement;
-import java.sql.Clob;
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.NClob;
-import java.sql.PreparedStatement;
-import java.sql.SQLClientInfoException;
-import java.sql.SQLException;
-import java.sql.SQLFeatureNotSupportedException;
-import java.sql.SQLWarning;
-import java.sql.SQLXML;
-import java.sql.Savepoint;
-import java.sql.Statement;
-import java.sql.Struct;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-import java.util.logging.Logger;
-import javax.sql.DataSource;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-public class ManagedConnectionBehaviorTest {
- @Test
- public void run() throws Exception {
- final GeronimoTransactionManager geronimoTransactionManager = new GeronimoTransactionManager((int) TimeUnit.MINUTES.toMillis(10));
- final TransactionManager mgr = new TransactionManagerWrapper(
- geronimoTransactionManager, "ManagedConnectionBehaviorTest", new GeronimoTransactionManagerFactory.GeronimoXAResourceWrapper());
-
- final MyDs myDs = new MyDs();
- final DataSource ds = new ManagedDataSource(myDs, geronimoTransactionManager, geronimoTransactionManager);
-
- { // no tx
- final Connection connection = ds.getConnection();
- assertTrue(myDs.connections.isEmpty()); // not yet needed
- connection.createBlob(); // just to call something
- assertFalse(myDs.connections.iterator().next().closed);
- connection.close();
- assertTrue(myDs.connections.iterator().next().closed);
- myDs.connections.clear();
- }
- { // tx
- mgr.begin();
- final Connection connection = ds.getConnection();
- assertTrue(myDs.connections.isEmpty()); // not yet needed
- connection.createBlob(); // just to call something
- assertFalse(myDs.connections.iterator().next().closed);
- mgr.commit();
- assertTrue(myDs.connections.iterator().next().closed);
- assertTrue(myDs.connections.iterator().next().commit);
- assertFalse(myDs.connections.iterator().next().rollback);
- myDs.connections.clear();
- }
- { // tx already init
- mgr.begin();
- final Connection connection = ds.getConnection();
- assertTrue(myDs.connections.isEmpty()); // not yet needed
- connection.createBlob(); // just to call something
- assertFalse(myDs.connections.iterator().next().closed);
- for (int i = 0; i < 5; i++) { // here the connection is already created, ensure we dont leak other connections
- connection.createBlob();
- }
- assertEquals(1, myDs.connections.size());
- mgr.commit();
- assertTrue(myDs.connections.iterator().next().closed);
- assertTrue(myDs.connections.iterator().next().commit);
- assertFalse(myDs.connections.iterator().next().rollback);
- myDs.connections.clear();
- }
- { // multiple tx
- mgr.begin();
- final Connection connection = ds.getConnection();
- assertTrue(myDs.connections.isEmpty()); // not yet needed
- connection.createBlob(); // just to call something
- assertFalse(myDs.connections.iterator().next().closed);
- final Transaction previous = mgr.suspend();
- mgr.begin();
- final Connection connection2 = ds.getConnection();
- connection2.createBlob();
- assertEquals(2, myDs.connections.size());
- mgr.commit();
- mgr.resume(previous);
- mgr.commit();
- final Iterator<MyConn> iterator = myDs.connections.iterator();
- final MyConn first = iterator.next();
- assertTrue(first.closed);
- assertTrue(first.commit);
- assertTrue(myDs.connections.iterator().next().commit);
- myDs.connections.clear();
- }
-
- }
-
- public static class MyDs implements DataSource {
- private final Collection<MyConn> connections = new LinkedList<>();
-
- @Override
- public Connection getConnection() throws SQLException {
- final MyConn myConn = new MyConn(this);
- connections.add(myConn);
- return myConn;
- }
-
- @Override
- public Connection getConnection(final String username, final String password) throws SQLException {
- return null;
- }
-
- @Override
- public PrintWriter getLogWriter() throws SQLException {
- return null;
- }
-
- @Override
- public void setLogWriter(final PrintWriter out) throws SQLException {
- // no-op
- }
-
- @Override
- public void setLoginTimeout(final int seconds) throws SQLException {
- // no-op
- }
-
- @Override
- public int getLoginTimeout() throws SQLException {
- return 0;
- }
-
- @Override
- public Logger getParentLogger() throws SQLFeatureNotSupportedException {
- return null;
- }
-
- @Override
- public <T> T unwrap(final Class<T> iface) throws SQLException {
- return null;
- }
-
- @Override
- public boolean isWrapperFor(final Class<?> iface) throws SQLException {
- return false;
- }
- }
-
- public static class MyConn implements Connection {
- private final MyDs parent;
- private Boolean autoCommit;
- private boolean commit;
- private boolean rollback;
- private boolean closed;
-
- public MyConn(final MyDs myDs) {
- this.parent = myDs;
- }
-
- @Override
- public Statement createStatement() throws SQLException {
- return null;
- }
-
- @Override
- public PreparedStatement prepareStatement(String sql) throws SQLException {
- return null;
- }
-
- @Override
- public CallableStatement prepareCall(String sql) throws SQLException {
- return null;
- }
-
- @Override
- public String nativeSQL(String sql) throws SQLException {
- return null;
- }
-
- @Override
- public void setAutoCommit(boolean autoCommit) throws SQLException {
- this.autoCommit = autoCommit;
- }
-
- @Override
- public boolean getAutoCommit() throws SQLException {
- return false;
- }
-
- @Override
- public void commit() throws SQLException {
- commit = true;
- }
-
- @Override
- public void rollback() throws SQLException {
- rollback = true;
- }
-
- @Override
- public void close() throws SQLException {
- closed = true;
- }
-
- @Override
- public boolean isClosed() throws SQLException {
- return closed;
- }
-
- @Override
- public DatabaseMetaData getMetaData() throws SQLException {
- return null;
- }
-
- @Override
- public void setReadOnly(final boolean readOnly) throws SQLException {
-
- }
-
- @Override
- public boolean isReadOnly() throws SQLException {
- return false;
- }
-
- @Override
- public void setCatalog(final String catalog) throws SQLException {
-
- }
-
- @Override
- public String getCatalog() throws SQLException {
- return null;
- }
-
- @Override
- public void setTransactionIsolation(final int level) throws SQLException {
-
- }
-
- @Override
- public int getTransactionIsolation() throws SQLException {
- return 0;
- }
-
- @Override
- public SQLWarning getWarnings() throws SQLException {
- return null;
- }
-
- @Override
- public void clearWarnings() throws SQLException {
-
- }
-
- @Override
- public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
- return null;
- }
-
- @Override
- public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
- return null;
- }
-
- @Override
- public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
- return null;
- }
-
- @Override
- public Map<String, Class<?>> getTypeMap() throws SQLException {
- return null;
- }
-
- @Override
- public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
-
- }
-
- @Override
- public void setHoldability(int holdability) throws SQLException {
-
- }
-
- @Override
- public int getHoldability() throws SQLException {
- return 0;
- }
-
- @Override
- public Savepoint setSavepoint() throws SQLException {
- return null;
- }
-
- @Override
- public Savepoint setSavepoint(String name) throws SQLException {
- return null;
- }
-
- @Override
- public void rollback(Savepoint savepoint) throws SQLException {
-
- }
-
- @Override
- public void releaseSavepoint(Savepoint savepoint) throws SQLException {
-
- }
-
- @Override
- public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
- return null;
- }
-
- @Override
- public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
- return null;
- }
-
- @Override
- public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
- return null;
- }
-
- @Override
- public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
- return null;
- }
-
- @Override
- public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
- return null;
- }
-
- @Override
- public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
- return null;
- }
-
- @Override
- public Clob createClob() throws SQLException {
- return null;
- }
-
- @Override
- public Blob createBlob() throws SQLException {
- return null;
- }
-
- @Override
- public NClob createNClob() throws SQLException {
- return null;
- }
-
- @Override
- public SQLXML createSQLXML() throws SQLException {
- return null;
- }
-
- @Override
- public boolean isValid(int timeout) throws SQLException {
- return false;
- }
-
- @Override
- public void setClientInfo(String name, String value) throws SQLClientInfoException {
-
- }
-
- @Override
- public void setClientInfo(Properties properties) throws SQLClientInfoException {
-
- }
-
- @Override
- public String getClientInfo(String name) throws SQLException {
- return null;
- }
-
- @Override
- public Properties getClientInfo() throws SQLException {
- return null;
- }
-
- @Override
- public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
- return null;
- }
-
- @Override
- public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
- return null;
- }
-
- @Override
- public void setSchema(String schema) throws SQLException {
-
- }
-
- @Override
- public String getSchema() throws SQLException {
- return null;
- }
-
- @Override
- public void abort(Executor executor) throws SQLException {
-
- }
-
- @Override
- public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
-
- }
-
- @Override
- public int getNetworkTimeout() throws SQLException {
- return 0;
- }
-
- @Override
- public <T> T unwrap(Class<T> iface) throws SQLException {
- return null;
- }
-
- @Override
- public boolean isWrapperFor(Class<?> iface) throws SQLException {
- return false;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/tomee/blob/1922c13c/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/ManagedDataSourceTest.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/ManagedDataSourceTest.java b/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/ManagedDataSourceTest.java
index f2005f5..e959693 100644
--- a/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/ManagedDataSourceTest.java
+++ b/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/ManagedDataSourceTest.java
@@ -19,18 +19,14 @@ package org.apache.openejb.resource.jdbc;
import org.apache.openejb.jee.EjbJar;
import org.apache.openejb.jee.SingletonBean;
import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.resource.jdbc.managed.local.ManagedConnection;
import org.apache.openejb.testing.Configuration;
import org.apache.openejb.testing.Module;
+import org.junit.After;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.Properties;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.EJBContext;
@@ -39,7 +35,17 @@ import javax.ejb.Singleton;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.sql.DataSource;
+import javax.transaction.Transaction;
+import java.lang.reflect.Field;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Map;
+import java.util.Properties;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -192,6 +198,15 @@ public class ManagedDataSourceTest {
assertFalse(exists(12));
}
+ @After
+ public void checkTxMapIsEmpty() throws Exception { // avoid memory leak
+ final Field map = ManagedConnection.class.getDeclaredField("CONNECTION_BY_TX_BY_DS");
+ map.setAccessible(true);
+ final Map<DataSource, Map<Transaction, Connection>> instance = (Map<DataSource, Map<Transaction, Connection>>) map.get(null);
+ assertEquals(1, instance.size());
+ assertEquals(0, instance.values().iterator().next().size());
+ }
+
private static boolean exists(final int id) throws SQLException {
final Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
final Statement statement = connection.createStatement();
http://git-wip-us.apache.org/repos/asf/tomee/blob/1922c13c/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/MultiThreadedManagedDataSourceTest.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/MultiThreadedManagedDataSourceTest.java b/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/MultiThreadedManagedDataSourceTest.java
index 7f908c6..15288fe 100644
--- a/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/MultiThreadedManagedDataSourceTest.java
+++ b/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/MultiThreadedManagedDataSourceTest.java
@@ -19,30 +19,35 @@ package org.apache.openejb.resource.jdbc;
import org.apache.openejb.jee.EjbJar;
import org.apache.openejb.jee.SingletonBean;
import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.resource.jdbc.managed.local.ManagedConnection;
import org.apache.openejb.testing.Configuration;
import org.apache.openejb.testing.Module;
+import org.junit.After;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
+import javax.annotation.Resource;
+import javax.ejb.EJB;
+import javax.ejb.EJBContext;
+import javax.ejb.LocalBean;
+import javax.ejb.Singleton;
+import javax.sql.DataSource;
+import javax.transaction.Transaction;
+import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
+import java.util.Map;
import java.util.Properties;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
-import javax.annotation.Resource;
-import javax.ejb.EJB;
-import javax.ejb.EJBContext;
-import javax.ejb.LocalBean;
-import javax.ejb.Singleton;
-import javax.sql.DataSource;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -187,6 +192,15 @@ public class MultiThreadedManagedDataSourceTest {
assertEquals(ok.get(), count("") - count);
}
+ @After
+ public void checkTxMapIsEmpty() throws Exception { // avoid memory leak
+ final Field map = ManagedConnection.class.getDeclaredField("CONNECTION_BY_TX_BY_DS");
+ map.setAccessible(true);
+ final Map<DataSource, Map<Transaction, Connection>> instance = (Map<DataSource, Map<Transaction, Connection>>) map.get(null);
+ assertEquals(1, instance.size());
+ assertEquals(0, instance.values().iterator().next().size());
+ }
+
private static boolean exists(final int id) throws SQLException {
return count(" WHERE ID = " + id) == 1;
}
http://git-wip-us.apache.org/repos/asf/tomee/blob/1922c13c/server/openejb-bonecp/src/main/java/org/apache/openejb/bonecp/BoneCPDataSourceCreator.java
----------------------------------------------------------------------
diff --git a/server/openejb-bonecp/src/main/java/org/apache/openejb/bonecp/BoneCPDataSourceCreator.java b/server/openejb-bonecp/src/main/java/org/apache/openejb/bonecp/BoneCPDataSourceCreator.java
index 37332dc..0cdb584 100644
--- a/server/openejb-bonecp/src/main/java/org/apache/openejb/bonecp/BoneCPDataSourceCreator.java
+++ b/server/openejb-bonecp/src/main/java/org/apache/openejb/bonecp/BoneCPDataSourceCreator.java
@@ -21,7 +21,6 @@ import com.jolbox.bonecp.BoneCPConfig;
import com.jolbox.bonecp.BoneCPDataSource;
import org.apache.openejb.OpenEJB;
import org.apache.openejb.OpenEJBRuntimeException;
-import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.resource.jdbc.BasicDataSourceUtil;
import org.apache.openejb.resource.jdbc.managed.xa.ManagedXADataSource;
import org.apache.openejb.resource.jdbc.plugin.DataSourcePlugin;
@@ -33,7 +32,6 @@ import org.apache.openejb.util.Strings;
import javax.sql.CommonDataSource;
import javax.sql.DataSource;
import javax.sql.XADataSource;
-import javax.transaction.TransactionSynchronizationRegistry;
import java.lang.reflect.Field;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
@@ -130,7 +128,7 @@ public class BoneCPDataSourceCreator extends PoolDataSourceCreator {
cleanProperty(ds, "xadatasource");
final XADataSource xaDs = XADataSourceResource.proxy(Thread.currentThread().getContextClassLoader(), xa);
- ds.setDatasourceBean(new ManagedXADataSource(xaDs, OpenEJB.getTransactionManager(), SystemInstance.get().getComponent(TransactionSynchronizationRegistry.class)));
+ ds.setDatasourceBean(new ManagedXADataSource(xaDs, OpenEJB.getTransactionManager()));
}
return ds;
http://git-wip-us.apache.org/repos/asf/tomee/blob/1922c13c/server/openejb-bonecp/src/test/java/org/apache/openejb/bonecp/BoneCPPooledDataSourceFromPoolTest.java
----------------------------------------------------------------------
diff --git a/server/openejb-bonecp/src/test/java/org/apache/openejb/bonecp/BoneCPPooledDataSourceFromPoolTest.java b/server/openejb-bonecp/src/test/java/org/apache/openejb/bonecp/BoneCPPooledDataSourceFromPoolTest.java
index 36f32b8..e9eba6c 100644
--- a/server/openejb-bonecp/src/test/java/org/apache/openejb/bonecp/BoneCPPooledDataSourceFromPoolTest.java
+++ b/server/openejb-bonecp/src/test/java/org/apache/openejb/bonecp/BoneCPPooledDataSourceFromPoolTest.java
@@ -21,16 +21,13 @@ import org.apache.openejb.jee.SingletonBean;
import org.apache.openejb.junit.ApplicationComposer;
import org.apache.openejb.junit.Configuration;
import org.apache.openejb.junit.Module;
+import org.apache.openejb.resource.jdbc.managed.local.ManagedConnection;
+import org.hsqldb.jdbc.JDBCDataSource;
+import org.junit.After;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.Properties;
import javax.annotation.Resource;
import javax.annotation.sql.DataSourceDefinition;
import javax.ejb.EJB;
@@ -40,7 +37,17 @@ import javax.ejb.Singleton;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.sql.DataSource;
+import javax.transaction.Transaction;
+import java.lang.reflect.Field;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Map;
+import java.util.Properties;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -188,7 +195,16 @@ public class BoneCPPooledDataSourceFromPoolTest {
assertFalse(exists(12));
}
- private static boolean exists(int id) throws SQLException {
+ @After
+ public void checkTxMapIsEmpty() throws Exception { // avoid memory leak
+ final Field map = ManagedConnection.class.getDeclaredField("CONNECTION_BY_TX_BY_DS");
+ map.setAccessible(true);
+ final Map<DataSource, Map<Transaction, Connection>> instance = (Map<DataSource, Map<Transaction, Connection>>) map.get(null);
+ assertEquals(1, instance.size());
+ assertEquals(0, instance.values().iterator().next().size());
+ }
+
+ private static boolean exists(final int id) throws SQLException {
final Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
final Statement statement = connection.createStatement();
final ResultSet result = statement.executeQuery("SELECT count(*) AS NB FROM " + TABLE + " WHERE ID = " + id);
http://git-wip-us.apache.org/repos/asf/tomee/blob/1922c13c/server/openejb-bonecp/src/test/java/org/apache/openejb/bonecp/BoneCPPooledDataSourceTest.java
----------------------------------------------------------------------
diff --git a/server/openejb-bonecp/src/test/java/org/apache/openejb/bonecp/BoneCPPooledDataSourceTest.java b/server/openejb-bonecp/src/test/java/org/apache/openejb/bonecp/BoneCPPooledDataSourceTest.java
index b5eb3aa..a2e705c 100644
--- a/server/openejb-bonecp/src/test/java/org/apache/openejb/bonecp/BoneCPPooledDataSourceTest.java
+++ b/server/openejb-bonecp/src/test/java/org/apache/openejb/bonecp/BoneCPPooledDataSourceTest.java
@@ -27,14 +27,6 @@ import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.lang.reflect.Field;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.Map;
-import java.util.Properties;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.EJBContext;
@@ -44,6 +36,14 @@ import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.sql.DataSource;
import javax.transaction.Transaction;
+import java.lang.reflect.Field;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Map;
+import java.util.Properties;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -196,7 +196,16 @@ public class BoneCPPooledDataSourceTest {
assertFalse(exists(12));
}
- private static boolean exists(int id) throws SQLException {
+ @After
+ public void checkTxMapIsEmpty() throws Exception { // avoid memory leak
+ final Field map = ManagedConnection.class.getDeclaredField("CONNECTION_BY_TX_BY_DS");
+ map.setAccessible(true);
+ final Map<DataSource, Map<Transaction, Connection>> instance = (Map<DataSource, Map<Transaction, Connection>>) map.get(null);
+ assertEquals(1, instance.size());
+ assertEquals(0, instance.values().iterator().next().size());
+ }
+
+ private static boolean exists(final int id) throws SQLException {
final Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
final Statement statement = connection.createStatement();
final ResultSet result = statement.executeQuery("SELECT count(*) AS NB FROM " + TABLE + " WHERE ID = " + id);
http://git-wip-us.apache.org/repos/asf/tomee/blob/1922c13c/server/openejb-bonecp/src/test/java/org/apache/openejb/bonecp/XABoneCPTest.java
----------------------------------------------------------------------
diff --git a/server/openejb-bonecp/src/test/java/org/apache/openejb/bonecp/XABoneCPTest.java b/server/openejb-bonecp/src/test/java/org/apache/openejb/bonecp/XABoneCPTest.java
index b9d3279..8677b9f 100644
--- a/server/openejb-bonecp/src/test/java/org/apache/openejb/bonecp/XABoneCPTest.java
+++ b/server/openejb-bonecp/src/test/java/org/apache/openejb/bonecp/XABoneCPTest.java
@@ -26,11 +26,11 @@ import org.hsqldb.jdbc.pool.JDBCXADataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
+import javax.annotation.Resource;
+import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
-import javax.annotation.Resource;
-import javax.sql.DataSource;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.junit.Assert.assertNotNull;
http://git-wip-us.apache.org/repos/asf/tomee/blob/1922c13c/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatDataSourceFromPoolTest.java
----------------------------------------------------------------------
diff --git a/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatDataSourceFromPoolTest.java b/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatDataSourceFromPoolTest.java
index 6cc369b..856c8e3 100644
--- a/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatDataSourceFromPoolTest.java
+++ b/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatDataSourceFromPoolTest.java
@@ -21,16 +21,12 @@ import org.apache.openejb.jee.SingletonBean;
import org.apache.openejb.junit.ApplicationComposer;
import org.apache.openejb.junit.Configuration;
import org.apache.openejb.junit.Module;
+import org.apache.openejb.resource.jdbc.managed.local.ManagedConnection;
+import org.junit.After;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.Properties;
import javax.annotation.Resource;
import javax.annotation.sql.DataSourceDefinition;
import javax.ejb.EJB;
@@ -40,7 +36,17 @@ import javax.ejb.Singleton;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.sql.DataSource;
+import javax.transaction.Transaction;
+import java.lang.reflect.Field;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Map;
+import java.util.Properties;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -188,6 +194,15 @@ public class TomcatDataSourceFromPoolTest {
assertFalse(exists(12));
}
+ @After
+ public void checkTxMapIsEmpty() throws Exception { // avoid memory leak
+ final Field map = ManagedConnection.class.getDeclaredField("CONNECTION_BY_TX_BY_DS");
+ map.setAccessible(true);
+ final Map<DataSource, Map<Transaction, Connection>> instance = (Map<DataSource, Map<Transaction, Connection>> ) map.get(null);
+ assertEquals(1, instance.size());
+ assertEquals(0, instance.values().iterator().next().size());
+ }
+
private static boolean exists(final int id) throws SQLException {
final Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
final Statement statement = connection.createStatement();
http://git-wip-us.apache.org/repos/asf/tomee/blob/1922c13c/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatPoolTest.java
----------------------------------------------------------------------
diff --git a/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatPoolTest.java b/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatPoolTest.java
index 658333f..7c8e959 100644
--- a/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatPoolTest.java
+++ b/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatPoolTest.java
@@ -21,16 +21,12 @@ import org.apache.openejb.jee.SingletonBean;
import org.apache.openejb.junit.ApplicationComposer;
import org.apache.openejb.junit.Configuration;
import org.apache.openejb.junit.Module;
+import org.apache.openejb.resource.jdbc.managed.local.ManagedConnection;
+import org.junit.After;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.Properties;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.EJBContext;
@@ -39,7 +35,17 @@ import javax.ejb.Singleton;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.sql.DataSource;
+import javax.transaction.Transaction;
+import java.lang.reflect.Field;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Map;
+import java.util.Properties;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -190,6 +196,15 @@ public class TomcatPoolTest {
assertFalse(exists(12));
}
+ @After
+ public void checkTxMapIsEmpty() throws Exception { // avoid memory leak
+ final Field map = ManagedConnection.class.getDeclaredField("CONNECTION_BY_TX_BY_DS");
+ map.setAccessible(true);
+ final Map<DataSource, Map<Transaction, Connection>> instance = (Map<DataSource, Map<Transaction, Connection>> ) map.get(null);
+ assertEquals(1, instance.size());
+ assertEquals(0, instance.values().iterator().next().size());
+ }
+
private static boolean exists(final int id) throws SQLException {
final Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
final Statement statement = connection.createStatement();