commons-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Romain Manni-Bucau (JIRA)" <j...@apache.org>
Subject [jira] [Updated] (DBCP-464) managed shared connections can lead to a NPE on close
Date Tue, 12 Jul 2016 04:51:10 GMT

     [ 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)

Mime
View raw message