[ https://issues.apache.org/jira/browse/DBCP-464?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Romain Manni-Bucau updated DBCP-464: ------------------------------------ Description: in CompletionListener the delegate will be set to false but the connection will not be closed so when calling close later and if the connection exited a transaction context then it will try to close it and lead to a NPE Here my workaround: {code} @Override protected DataSource createDataSourceInstance() throws SQLException { final TransactionRegistry transactionRegistry = getTransactionRegistry(); if (transactionRegistry == null) { throw new IllegalStateException("TransactionRegistry has not been set"); } if (getConnectionPool() == null) { throw new IllegalStateException("Pool has not been set"); } final PoolingDataSource<PoolableConnection> pds = new ManagedDataSource<PoolableConnection>(getConnectionPool(), transactionRegistry) { @Override public Connection getConnection() throws SQLException { return new ManagedConnection<PoolableConnection>(getPool(), transactionRegistry, isAccessToUnderlyingConnectionAllowed()) { @Override public void close() throws SQLException { if (!isClosedInternal()) { try { if (null != getDelegateInternal()) { super.close(); } } finally { setClosedInternal(true); } } } @Override public boolean isClosed() throws SQLException { return isClosedInternal() || null != getDelegateInternal() && getDelegateInternal().isClosed(); } }; } }; pds.setAccessToUnderlyingConnectionAllowed(isAccessToUnderlyingConnectionAllowed()); return pds; } {code} was: in CompletionListener the delegate will be set to false but the connection will not be closed so when calling close later and if the connection exited a transaction context then it will try to close it and lead to a NPE Here my workaround: {code} @Override protected DataSource createDataSourceInstance() throws SQLException { final TransactionRegistry transactionRegistry = getTransactionRegistry(); if (transactionRegistry == null) { throw new IllegalStateException("TransactionRegistry has not been set"); } if (getConnectionPool() == null) { throw new IllegalStateException("Pool has not been set"); } final PoolingDataSource<PoolableConnection> pds = new ManagedDataSource<PoolableConnection>(getConnectionPool(), transactionRegistry) { @Override public Connection getConnection() throws SQLException { return new ManagedConnection<PoolableConnection>(getPool(), transactionRegistry, isAccessToUnderlyingConnectionAllowed()) { @Override public void close() throws SQLException { // here is the additional check to do if (getDelegateInternal() == null) { return; } super.close(); } }; } }; pds.setAccessToUnderlyingConnectionAllowed(isAccessToUnderlyingConnectionAllowed()); return pds; } {code} > managed shared connections can lead to a NPE on close > ----------------------------------------------------- > > Key: DBCP-464 > URL: https://issues.apache.org/jira/browse/DBCP-464 > Project: Commons Dbcp > Issue Type: Bug > Affects Versions: 1.4, 2.1 > Reporter: Romain Manni-Bucau > > in CompletionListener the delegate will be set to false but the connection > will not be closed so when calling close later and if the connection exited a > transaction context then it will try to close it and lead to a NPE > Here my workaround: > {code} > @Override > protected DataSource createDataSourceInstance() throws SQLException { > final TransactionRegistry transactionRegistry = > getTransactionRegistry(); > if (transactionRegistry == null) { > throw new IllegalStateException("TransactionRegistry has not been > set"); > } > if (getConnectionPool() == null) { > throw new IllegalStateException("Pool has not been set"); > } > final PoolingDataSource<PoolableConnection> pds = new > ManagedDataSource<PoolableConnection>(getConnectionPool(), > transactionRegistry) { > @Override > public Connection getConnection() throws SQLException { > return new ManagedConnection<PoolableConnection>(getPool(), > transactionRegistry, isAccessToUnderlyingConnectionAllowed()) { > @Override > public void close() throws SQLException { > if (!isClosedInternal()) { > try { > if (null != getDelegateInternal()) { > super.close(); > } > } finally { > setClosedInternal(true); > } > } > } > > @Override > public boolean isClosed() throws SQLException { > return isClosedInternal() || null != > getDelegateInternal() && getDelegateInternal().isClosed(); > } > }; > } > }; > > pds.setAccessToUnderlyingConnectionAllowed(isAccessToUnderlyingConnectionAllowed()); > return pds; > } > {code} -- This message was sent by Atlassian JIRA (v6.3.4#6332)