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 <[email protected]> Authored: Thu Jul 30 13:46:42 2015 +0100 Committer: Jonathan Gallimore <[email protected]> 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();
