You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2021/01/15 17:19:24 UTC

[tomcat] branch 8.5.x updated (6dcb374 -> 5601e51)

This is an automated email from the ASF dual-hosted git repository.

markt pushed a change to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git.


    from 6dcb374  Update Commons Pool 2 to 2.9.1-SNAPSHOT
     new 2aaffcd  Update Commons DBCP
     new 5601e51  Fix back-port of Pool2 update not to use default methods

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 MERGE.txt                                          |   2 +-
 .../apache/tomcat/dbcp/dbcp2/BasicDataSource.java  |  24 ++---
 .../tomcat/dbcp/dbcp2/BasicDataSourceFactory.java  |  40 ++++---
 .../tomcat/dbcp/dbcp2/BasicDataSourceMXBean.java   |   5 +-
 .../tomcat/dbcp/dbcp2/DelegatingConnection.java    |  18 ++--
 .../dbcp/dbcp2/DelegatingDatabaseMetaData.java     |   3 +-
 .../tomcat/dbcp/dbcp2/DelegatingResultSet.java     |   6 +-
 .../tomcat/dbcp/dbcp2/DelegatingStatement.java     |  17 ++-
 .../tomcat/dbcp/dbcp2/DriverConnectionFactory.java |  13 +--
 .../apache/tomcat/dbcp/dbcp2/DriverFactory.java    |   6 +-
 .../org/apache/tomcat/dbcp/dbcp2/Jdbc41Bridge.java |  26 +++--
 .../dbcp/dbcp2/LifetimeExceededException.java      |   1 -
 .../tomcat/dbcp/dbcp2/ObjectNameWrapper.java       |   8 +-
 java/org/apache/tomcat/dbcp/dbcp2/PStmtKey.java    |  71 +++----------
 .../dbcp/dbcp2/PoolableCallableStatement.java      |   4 +-
 .../tomcat/dbcp/dbcp2/PoolableConnection.java      |  20 +++-
 .../dbcp/dbcp2/PoolableConnectionFactory.java      |  41 ++++---
 .../dbcp/dbcp2/PoolablePreparedStatement.java      |   8 +-
 .../tomcat/dbcp/dbcp2/PoolingConnection.java       |  17 ++-
 .../tomcat/dbcp/dbcp2/PoolingDataSource.java       |   4 +-
 .../apache/tomcat/dbcp/dbcp2/PoolingDriver.java    |  16 ++-
 .../apache/tomcat/dbcp/dbcp2/SQLExceptionList.java |   2 +-
 java/org/apache/tomcat/dbcp/dbcp2/Utils.java       |  45 +++++---
 .../dbcp/dbcp2/cpdsadapter/ConnectionImpl.java     |   4 +-
 .../dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java  | 118 +++++++--------------
 .../dbcp/dbcp2/cpdsadapter/PStmtKeyCPDS.java       |   4 +-
 .../dbcp2/cpdsadapter/PooledConnectionImpl.java    |  55 ++++++++--
 .../dbcp2/datasources/CPDSConnectionFactory.java   |  19 ++--
 .../dbcp2/datasources/InstanceKeyDataSource.java   |   7 --
 .../datasources/InstanceKeyDataSourceFactory.java  |  18 ++--
 .../datasources/KeyedCPDSConnectionFactory.java    |  20 ++--
 .../tomcat/dbcp/dbcp2/datasources/PoolKey.java     |  26 ++---
 .../tomcat/dbcp/dbcp2/datasources/UserPassKey.java |  23 +---
 .../dbcp/dbcp2/datasources/package-info.java       |   2 +-
 .../apache/tomcat/dbcp/pool2/KeyedObjectPool.java  |   4 +-
 .../dbcp/pool2/KeyedPooledObjectFactory.java       |   4 +-
 java/org/apache/tomcat/dbcp/pool2/ObjectPool.java  |   4 +-
 java/org/apache/tomcat/dbcp/pool2/PoolUtils.java   |  10 ++
 .../tomcat/dbcp/pool2/PooledObjectFactory.java     |   4 +-
 .../dbcp/pool2/impl/SoftReferenceObjectPool.java   |   6 ++
 webapps/docs/changelog.xml                         |   4 +
 41 files changed, 346 insertions(+), 383 deletions(-)


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[tomcat] 01/02: Update Commons DBCP

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 2aaffcd5fb05daa4ee138b59c84ec3a66be3961d
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri Jan 15 15:42:38 2021 +0000

    Update Commons DBCP
---
 MERGE.txt                                          |   2 +-
 .../apache/tomcat/dbcp/dbcp2/BasicDataSource.java  |  24 ++---
 .../tomcat/dbcp/dbcp2/BasicDataSourceFactory.java  |  40 ++++---
 .../tomcat/dbcp/dbcp2/BasicDataSourceMXBean.java   |   5 +-
 .../tomcat/dbcp/dbcp2/DelegatingConnection.java    |  18 ++--
 .../dbcp/dbcp2/DelegatingDatabaseMetaData.java     |   3 +-
 .../tomcat/dbcp/dbcp2/DelegatingResultSet.java     |   6 +-
 .../tomcat/dbcp/dbcp2/DelegatingStatement.java     |  17 ++-
 .../tomcat/dbcp/dbcp2/DriverConnectionFactory.java |  13 +--
 .../apache/tomcat/dbcp/dbcp2/DriverFactory.java    |   6 +-
 .../org/apache/tomcat/dbcp/dbcp2/Jdbc41Bridge.java |  26 +++--
 .../dbcp/dbcp2/LifetimeExceededException.java      |   1 -
 .../tomcat/dbcp/dbcp2/ObjectNameWrapper.java       |   8 +-
 java/org/apache/tomcat/dbcp/dbcp2/PStmtKey.java    |  71 +++----------
 .../dbcp/dbcp2/PoolableCallableStatement.java      |   4 +-
 .../tomcat/dbcp/dbcp2/PoolableConnection.java      |  20 +++-
 .../dbcp/dbcp2/PoolableConnectionFactory.java      |  41 ++++---
 .../dbcp/dbcp2/PoolablePreparedStatement.java      |   8 +-
 .../tomcat/dbcp/dbcp2/PoolingConnection.java       |  17 ++-
 .../tomcat/dbcp/dbcp2/PoolingDataSource.java       |   4 +-
 .../apache/tomcat/dbcp/dbcp2/PoolingDriver.java    |  16 ++-
 .../apache/tomcat/dbcp/dbcp2/SQLExceptionList.java |   2 +-
 java/org/apache/tomcat/dbcp/dbcp2/Utils.java       |  45 +++++---
 .../dbcp/dbcp2/cpdsadapter/ConnectionImpl.java     |   4 +-
 .../dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java  | 118 +++++++--------------
 .../dbcp/dbcp2/cpdsadapter/PStmtKeyCPDS.java       |   4 +-
 .../dbcp2/cpdsadapter/PooledConnectionImpl.java    |  55 ++++++++--
 .../dbcp2/datasources/CPDSConnectionFactory.java   |  19 ++--
 .../dbcp2/datasources/InstanceKeyDataSource.java   |   7 --
 .../datasources/InstanceKeyDataSourceFactory.java  |  18 ++--
 .../datasources/KeyedCPDSConnectionFactory.java    |  20 ++--
 .../tomcat/dbcp/dbcp2/datasources/PoolKey.java     |  26 ++---
 .../tomcat/dbcp/dbcp2/datasources/UserPassKey.java |  23 +---
 .../dbcp/dbcp2/datasources/package-info.java       |   2 +-
 webapps/docs/changelog.xml                         |   4 +
 35 files changed, 326 insertions(+), 371 deletions(-)

diff --git a/MERGE.txt b/MERGE.txt
index 52851d9..806669a 100644
--- a/MERGE.txt
+++ b/MERGE.txt
@@ -69,4 +69,4 @@ Sub-tree
 src/main/java/org/apache/commons/dbcp2
 src/main/resources/org/apache/commons/dbcp2
 The SHA1 ID / tag for the most recent commit to be merged to Tomcat is:
-6d232e547d5725e419832fc514fc0348aa897e7c (2020-08-11)
+e24196a95bbbc531eb3c5f1b19e1dc42fd78a783 (2021-01-15)
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.java b/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.java
index 61afa6f..8f11d75 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.java
@@ -539,7 +539,7 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
 
             // Set up the poolable connection factory
             boolean success = false;
-            PoolableConnectionFactory poolableConnectionFactory;
+            final PoolableConnectionFactory poolableConnectionFactory;
             try {
                 poolableConnectionFactory = createPoolableConnectionFactory(driverConnectionFactory);
                 poolableConnectionFactory.setPoolStatements(poolPreparedStatements);
@@ -616,7 +616,7 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
      */
     protected GenericObjectPool<PoolableConnection> createObjectPool(final PoolableConnectionFactory factory,
             final GenericObjectPoolConfig<PoolableConnection> poolConfig, final AbandonedConfig abandonedConfig) {
-        GenericObjectPool<PoolableConnection> gop;
+        final GenericObjectPool<PoolableConnection> gop;
         if (abandonedConfig != null && (abandonedConfig.getRemoveAbandonedOnBorrow()
                 || abandonedConfig.getRemoveAbandonedOnMaintenance())) {
             gop = new GenericObjectPool<>(factory, poolConfig, abandonedConfig);
@@ -697,7 +697,7 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
      */
     @Override
     public boolean getAbandonedUsageTracking() {
-        return abandonedConfig == null ? false : abandonedConfig.getUseUsageTracking();
+        return abandonedConfig != null && abandonedConfig.getUseUsageTracking();
     }
 
     /**
@@ -793,8 +793,7 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
      */
     @Override
     public String[] getConnectionInitSqlsAsArray() {
-        final Collection<String> result = getConnectionInitSqls();
-        return result.toArray(new String[0]);
+        return getConnectionInitSqls().toArray(Utils.EMPTY_STRING_ARRAY);
     }
 
     protected GenericObjectPool<PoolableConnection> getConnectionPool() {
@@ -889,8 +888,7 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
      */
     @Override
     public String[] getDisconnectionSqlCodesAsArray() {
-        final Collection<String> result = getDisconnectionSqlCodes();
-        return result.toArray(new String[0]);
+        return getDisconnectionSqlCodes().toArray(Utils.EMPTY_STRING_ARRAY);
     }
 
     /**
@@ -1013,7 +1011,7 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
      */
     @Override
     public boolean getLogAbandoned() {
-        return abandonedConfig == null ? false : abandonedConfig.getLogAbandoned();
+        return abandonedConfig != null && abandonedConfig.getLogAbandoned();
     }
 
     /**
@@ -1228,7 +1226,7 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
      */
     @Override
     public boolean getRemoveAbandonedOnBorrow() {
-        return abandonedConfig == null ? false : abandonedConfig.getRemoveAbandonedOnBorrow();
+        return abandonedConfig != null && abandonedConfig.getRemoveAbandonedOnBorrow();
     }
 
     /**
@@ -1249,7 +1247,7 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
      */
     @Override
     public boolean getRemoveAbandonedOnMaintenance() {
-        return abandonedConfig == null ? false : abandonedConfig.getRemoveAbandonedOnMaintenance();
+        return abandonedConfig != null && abandonedConfig.getRemoveAbandonedOnMaintenance();
     }
 
     /**
@@ -1477,8 +1475,8 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
      * @param value the string to test, may be null.
      * @return boolean false if value is null, otherwise {@link String#isEmpty()}.
      */
-    private boolean isEmpty(String value) {
-        return value == null ? true : value.trim().isEmpty();
+    private boolean isEmpty(final String value) {
+        return value == null || value.trim().isEmpty();
     }
 
     /**
@@ -1526,7 +1524,7 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
      *
      * @since 2.7.0
      */
-    protected void log(String message, Throwable throwable) {
+    protected void log(final String message, final Throwable throwable) {
         if (logWriter != null) {
             logWriter.println(message);
             throwable.printStackTrace(logWriter);
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceFactory.java b/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceFactory.java
index b8ae8f2..0b11b07 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceFactory.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceFactory.java
@@ -49,7 +49,7 @@ import org.apache.tomcat.dbcp.pool2.impl.GenericObjectPoolConfig;
  * <code>BasicDataSource</code> bean properties with the following exceptions:
  * </p>
  * <ul>
- * <li><code>connectionInitSqls</code> must be passed to this factory as a single String using semi-colon to delimit the
+ * <li><code>connectionInitSqls</code> must be passed to this factory as a single String using semicolon to delimit the
  * statements whereas <code>BasicDataSource</code> requires a collection of Strings.</li>
  * </ul>
  *
@@ -299,9 +299,7 @@ public class BasicDataSourceFactory implements ObjectFactory {
      */
     public static BasicDataSource createDataSource(final Properties properties) throws Exception {
         final BasicDataSource dataSource = new BasicDataSource();
-        String value = null;
-
-        value = properties.getProperty(PROP_DEFAULT_AUTO_COMMIT);
+        String value = properties.getProperty(PROP_DEFAULT_AUTO_COMMIT);
         if (value != null) {
             dataSource.setDefaultAutoCommit(Boolean.valueOf(value));
         }
@@ -349,7 +347,7 @@ public class BasicDataSourceFactory implements ObjectFactory {
 
         value = properties.getProperty(PROP_CACHE_STATE);
         if (value != null) {
-            dataSource.setCacheState(Boolean.valueOf(value).booleanValue());
+            dataSource.setCacheState(Boolean.parseBoolean(value));
         }
 
         value = properties.getProperty(PROP_DRIVER_CLASS_NAME);
@@ -359,7 +357,7 @@ public class BasicDataSourceFactory implements ObjectFactory {
 
         value = properties.getProperty(PROP_LIFO);
         if (value != null) {
-            dataSource.setLifo(Boolean.valueOf(value).booleanValue());
+            dataSource.setLifo(Boolean.parseBoolean(value));
         }
 
         value = properties.getProperty(PROP_MAX_TOTAL);
@@ -389,17 +387,17 @@ public class BasicDataSourceFactory implements ObjectFactory {
 
         value = properties.getProperty(PROP_TEST_ON_CREATE);
         if (value != null) {
-            dataSource.setTestOnCreate(Boolean.valueOf(value).booleanValue());
+            dataSource.setTestOnCreate(Boolean.parseBoolean(value));
         }
 
         value = properties.getProperty(PROP_TEST_ON_BORROW);
         if (value != null) {
-            dataSource.setTestOnBorrow(Boolean.valueOf(value).booleanValue());
+            dataSource.setTestOnBorrow(Boolean.parseBoolean(value));
         }
 
         value = properties.getProperty(PROP_TEST_ON_RETURN);
         if (value != null) {
-            dataSource.setTestOnReturn(Boolean.valueOf(value).booleanValue());
+            dataSource.setTestOnReturn(Boolean.parseBoolean(value));
         }
 
         value = properties.getProperty(PROP_TIME_BETWEEN_EVICTION_RUNS_MILLIS);
@@ -429,7 +427,7 @@ public class BasicDataSourceFactory implements ObjectFactory {
 
         value = properties.getProperty(PROP_TEST_WHILE_IDLE);
         if (value != null) {
-            dataSource.setTestWhileIdle(Boolean.valueOf(value).booleanValue());
+            dataSource.setTestWhileIdle(Boolean.parseBoolean(value));
         }
 
         value = properties.getProperty(PROP_PASSWORD);
@@ -459,17 +457,17 @@ public class BasicDataSourceFactory implements ObjectFactory {
 
         value = properties.getProperty(PROP_ACCESS_TO_UNDERLYING_CONNECTION_ALLOWED);
         if (value != null) {
-            dataSource.setAccessToUnderlyingConnectionAllowed(Boolean.valueOf(value).booleanValue());
+            dataSource.setAccessToUnderlyingConnectionAllowed(Boolean.parseBoolean(value));
         }
 
         value = properties.getProperty(PROP_REMOVE_ABANDONED_ON_BORROW);
         if (value != null) {
-            dataSource.setRemoveAbandonedOnBorrow(Boolean.valueOf(value).booleanValue());
+            dataSource.setRemoveAbandonedOnBorrow(Boolean.parseBoolean(value));
         }
 
         value = properties.getProperty(PROP_REMOVE_ABANDONED_ON_MAINTENANCE);
         if (value != null) {
-            dataSource.setRemoveAbandonedOnMaintenance(Boolean.valueOf(value).booleanValue());
+            dataSource.setRemoveAbandonedOnMaintenance(Boolean.parseBoolean(value));
         }
 
         value = properties.getProperty(PROP_REMOVE_ABANDONED_TIMEOUT);
@@ -479,22 +477,22 @@ public class BasicDataSourceFactory implements ObjectFactory {
 
         value = properties.getProperty(PROP_LOG_ABANDONED);
         if (value != null) {
-            dataSource.setLogAbandoned(Boolean.valueOf(value).booleanValue());
+            dataSource.setLogAbandoned(Boolean.parseBoolean(value));
         }
 
         value = properties.getProperty(PROP_ABANDONED_USAGE_TRACKING);
         if (value != null) {
-            dataSource.setAbandonedUsageTracking(Boolean.valueOf(value).booleanValue());
+            dataSource.setAbandonedUsageTracking(Boolean.parseBoolean(value));
         }
 
         value = properties.getProperty(PROP_POOL_PREPARED_STATEMENTS);
         if (value != null) {
-            dataSource.setPoolPreparedStatements(Boolean.valueOf(value).booleanValue());
+            dataSource.setPoolPreparedStatements(Boolean.parseBoolean(value));
         }
 
         value = properties.getProperty(PROP_CLEAR_STATEMENT_POOL_ON_RETURN);
         if (value != null) {
-            dataSource.setClearStatementPoolOnReturn(Boolean.valueOf(value).booleanValue());
+            dataSource.setClearStatementPoolOnReturn(Boolean.parseBoolean(value));
         }
 
         value = properties.getProperty(PROP_MAX_OPEN_PREPARED_STATEMENTS);
@@ -524,7 +522,7 @@ public class BasicDataSourceFactory implements ObjectFactory {
 
         value = properties.getProperty(PROP_LOG_EXPIRED_CONNECTIONS);
         if (value != null) {
-            dataSource.setLogExpiredConnections(Boolean.valueOf(value).booleanValue());
+            dataSource.setLogExpiredConnections(Boolean.parseBoolean(value));
         }
 
         value = properties.getProperty(PROP_JMX_NAME);
@@ -534,12 +532,12 @@ public class BasicDataSourceFactory implements ObjectFactory {
 
         value = properties.getProperty(PROP_ENABLE_AUTO_COMMIT_ON_RETURN);
         if (value != null) {
-            dataSource.setAutoCommitOnReturn(Boolean.valueOf(value).booleanValue());
+            dataSource.setAutoCommitOnReturn(Boolean.parseBoolean(value));
         }
 
         value = properties.getProperty(PROP_ROLLBACK_ON_RETURN);
         if (value != null) {
-            dataSource.setRollbackOnReturn(Boolean.valueOf(value).booleanValue());
+            dataSource.setRollbackOnReturn(Boolean.parseBoolean(value));
         }
 
         value = properties.getProperty(PROP_DEFAULT_QUERY_TIMEOUT);
@@ -549,7 +547,7 @@ public class BasicDataSourceFactory implements ObjectFactory {
 
         value = properties.getProperty(PROP_FAST_FAIL_VALIDATION);
         if (value != null) {
-            dataSource.setFastFailValidation(Boolean.valueOf(value).booleanValue());
+            dataSource.setFastFailValidation(Boolean.parseBoolean(value));
         }
 
         value = properties.getProperty(PROP_DISCONNECTION_SQL_CODES);
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceMXBean.java b/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceMXBean.java
index 564a630..8cd178d 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceMXBean.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceMXBean.java
@@ -329,15 +329,16 @@ public interface BasicDataSourceMXBean {
      *
      * @throws SQLException if an error occurs initializing the datasource
      *
-     * @since 2.8
+     * @since 2.8.0
      */
     void start() throws SQLException;
 
     /**
      * See {@link BasicDataSource#restart()}
+     *
      * @throws SQLException if an error occurs initializing the datasource
      *
-     * @since 2.8
+     * @since 2.8.0
      */
     void restart() throws SQLException;
 }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingConnection.java b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingConnection.java
index 45e4dd6..5c02916 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingConnection.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingConnection.java
@@ -80,7 +80,6 @@ public class DelegatingConnection<C extends Connection> extends AbandonedTrace i
      *            the {@link Connection} to delegate all calls to.
      */
     public DelegatingConnection(final C c) {
-        super();
         connection = c;
     }
 
@@ -97,14 +96,12 @@ public class DelegatingConnection<C extends Connection> extends AbandonedTrace i
                 if (conn.isClosed()) {
                     str = "connection is closed";
                 } else {
-                    final StringBuffer sb = new StringBuffer();
+                    final StringBuilder sb = new StringBuilder();
                     sb.append(hashCode());
                     final DatabaseMetaData meta = conn.getMetaData();
                     if (meta != null) {
                         sb.append(", URL=");
                         sb.append(meta.getURL());
-                        sb.append(", UserName=");
-                        sb.append(meta.getUserName());
                         sb.append(", ");
                         sb.append(meta.getDriverName());
                         str = sb.toString();
@@ -171,7 +168,7 @@ public class DelegatingConnection<C extends Connection> extends AbandonedTrace i
      */
     public final Connection getInnermostDelegateInternal() {
         Connection conn = connection;
-        while (conn != null && conn instanceof DelegatingConnection) {
+        while (conn instanceof DelegatingConnection) {
             conn = ((DelegatingConnection<?>) conn).getDelegateInternal();
             if (this == conn) {
                 return null;
@@ -619,11 +616,11 @@ public class DelegatingConnection<C extends Connection> extends AbandonedTrace i
         final List<AbandonedTrace> traces = getTrace();
         if (traces != null && !traces.isEmpty()) {
             final List<Exception> thrownList = new ArrayList<>();
-            for (Object trace : traces) {
+            for (final Object trace : traces) {
                 if (trace instanceof Statement) {
                     try {
                         ((Statement) trace).close();
-                    } catch (Exception e) {
+                    } catch (final Exception e) {
                         thrownList.add(e);
                     }
                 } else if (trace instanceof ResultSet) {
@@ -631,7 +628,7 @@ public class DelegatingConnection<C extends Connection> extends AbandonedTrace i
                     // generated via DatabaseMetaData
                     try {
                         ((ResultSet) trace).close();
-                    } catch (Exception e) {
+                    } catch (final Exception e) {
                         thrownList.add(e);
                     }
                 }
@@ -767,7 +764,7 @@ public class DelegatingConnection<C extends Connection> extends AbandonedTrace i
     }
 
     @Override
-    public PreparedStatement prepareStatement(final String sql, final int columnIndexes[]) throws SQLException {
+    public PreparedStatement prepareStatement(final String sql, final int[] columnIndexes) throws SQLException {
         checkOpen();
         try {
             final DelegatingPreparedStatement dps = new DelegatingPreparedStatement(this,
@@ -781,7 +778,7 @@ public class DelegatingConnection<C extends Connection> extends AbandonedTrace i
     }
 
     @Override
-    public PreparedStatement prepareStatement(final String sql, final String columnNames[]) throws SQLException {
+    public PreparedStatement prepareStatement(final String sql, final String[] columnNames) throws SQLException {
         checkOpen();
         try {
             final DelegatingPreparedStatement dps = new DelegatingPreparedStatement(this,
@@ -964,7 +961,6 @@ public class DelegatingConnection<C extends Connection> extends AbandonedTrace i
 
     @Override
     public void abort(final Executor executor) throws SQLException {
-        checkOpen();
         try {
             Jdbc41Bridge.abort(connection, executor);
         } catch (final SQLException e) {
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingDatabaseMetaData.java b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingDatabaseMetaData.java
index a3f9bc1..571187a 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingDatabaseMetaData.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingDatabaseMetaData.java
@@ -51,7 +51,6 @@ public class DelegatingDatabaseMetaData implements DatabaseMetaData {
      */
     public DelegatingDatabaseMetaData(final DelegatingConnection<?> connection,
             final DatabaseMetaData databaseMetaData) {
-        super();
         this.connection = connection;
         this.databaseMetaData = databaseMetaData;
     }
@@ -439,7 +438,7 @@ public class DelegatingDatabaseMetaData implements DatabaseMetaData {
      */
     public DatabaseMetaData getInnermostDelegate() {
         DatabaseMetaData m = databaseMetaData;
-        while (m != null && m instanceof DelegatingDatabaseMetaData) {
+        while (m instanceof DelegatingDatabaseMetaData) {
             m = ((DelegatingDatabaseMetaData) m).getDelegate();
             if (this == m) {
                 return null;
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingResultSet.java b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingResultSet.java
index c5650f5..f0d8484 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingResultSet.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingResultSet.java
@@ -606,7 +606,7 @@ public final class DelegatingResultSet extends AbandonedTrace implements ResultS
      */
     public ResultSet getInnermostDelegate() {
         ResultSet r = resultSet;
-        while (r != null && r instanceof DelegatingResultSet) {
+        while (r instanceof DelegatingResultSet) {
             r = ((DelegatingResultSet) r).getDelegate();
             if (this == r) {
                 return null;
@@ -1045,9 +1045,9 @@ public final class DelegatingResultSet extends AbandonedTrace implements ResultS
     }
 
     protected void handleException(final SQLException e) throws SQLException {
-        if (statement != null && statement instanceof DelegatingStatement) {
+        if (statement instanceof DelegatingStatement) {
             ((DelegatingStatement) statement).handleException(e);
-        } else if (connection != null && connection instanceof DelegatingConnection) {
+        } else if (connection instanceof DelegatingConnection) {
             ((DelegatingConnection<?>) connection).handleException(e);
         } else {
             throw e;
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingStatement.java b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingStatement.java
index 9f5fec1..770680e 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingStatement.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingStatement.java
@@ -139,13 +139,12 @@ public class DelegatingStatement extends AbandonedTrace implements Statement {
             // See bug 17301 for what could happen when ResultSets are closed twice.
             final List<AbandonedTrace> resultSetList = getTrace();
             if (resultSetList != null) {
-                final int size = resultSetList.size();
-                final ResultSet[] resultSets = resultSetList.toArray(new ResultSet[size]);
+                final ResultSet[] resultSets = resultSetList.toArray(Utils.EMPTY_RESULT_SET_ARRAY);
                 for (final ResultSet resultSet : resultSets) {
                     if (resultSet != null) {
                         try {
                             resultSet.close();
-                        } catch (Exception e) {
+                        } catch (final Exception e) {
                             if (connection != null) {
                                 // Does not rethrow e.
                                 connection.handleExceptionNoThrow(e);
@@ -159,7 +158,7 @@ public class DelegatingStatement extends AbandonedTrace implements Statement {
             if (statement != null) {
                 try {
                     statement.close();
-                } catch (Exception e) {
+                } catch (final Exception e) {
                     if (connection != null) {
                         // Does not rethrow e.
                         connection.handleExceptionNoThrow(e);
@@ -211,7 +210,7 @@ public class DelegatingStatement extends AbandonedTrace implements Statement {
     }
 
     @Override
-    public boolean execute(final String sql, final int columnIndexes[]) throws SQLException {
+    public boolean execute(final String sql, final int[] columnIndexes) throws SQLException {
         checkOpen();
         setLastUsedInParent();
         try {
@@ -223,7 +222,7 @@ public class DelegatingStatement extends AbandonedTrace implements Statement {
     }
 
     @Override
-    public boolean execute(final String sql, final String columnNames[]) throws SQLException {
+    public boolean execute(final String sql, final String[] columnNames) throws SQLException {
         checkOpen();
         setLastUsedInParent();
         try {
@@ -283,7 +282,7 @@ public class DelegatingStatement extends AbandonedTrace implements Statement {
     }
 
     @Override
-    public int executeUpdate(final String sql, final int columnIndexes[]) throws SQLException {
+    public int executeUpdate(final String sql, final int[] columnIndexes) throws SQLException {
         checkOpen();
         setLastUsedInParent();
         try {
@@ -295,7 +294,7 @@ public class DelegatingStatement extends AbandonedTrace implements Statement {
     }
 
     @Override
-    public int executeUpdate(final String sql, final String columnNames[]) throws SQLException {
+    public int executeUpdate(final String sql, final String[] columnNames) throws SQLException {
         checkOpen();
         setLastUsedInParent();
         try {
@@ -391,7 +390,7 @@ public class DelegatingStatement extends AbandonedTrace implements Statement {
      */
     public Statement getInnermostDelegate() {
         Statement s = statement;
-        while (s != null && s instanceof DelegatingStatement) {
+        while (s instanceof DelegatingStatement) {
             s = ((DelegatingStatement) s).getDelegate();
             if (this == s) {
                 return null;
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/DriverConnectionFactory.java b/java/org/apache/tomcat/dbcp/dbcp2/DriverConnectionFactory.java
index 45444ec..a575291 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/DriverConnectionFactory.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/DriverConnectionFactory.java
@@ -37,12 +37,9 @@ public class DriverConnectionFactory implements ConnectionFactory {
     /**
      * Constructs a connection factory for a given Driver.
      *
-     * @param driver
-     *            The Driver.
-     * @param connectString
-     *            The connection string.
-     * @param properties
-     *            The connection properties.
+     * @param driver The Driver.
+     * @param connectString The connection string.
+     * @param properties The connection properties.
      */
     public DriverConnectionFactory(final Driver driver, final String connectString, final Properties properties) {
         this.driver = driver;
@@ -81,7 +78,7 @@ public class DriverConnectionFactory implements ConnectionFactory {
 
     @Override
     public String toString() {
-        return this.getClass().getName() + " [" + String.valueOf(driver) + ";" + String.valueOf(connectionString) + ";"
-                + String.valueOf(properties) + "]";
+        return this.getClass().getName() + " [" + driver + ";" + connectionString + ";"
+            + Utils.cloneWithoutCredentials(properties) + "]";
     }
 }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/DriverFactory.java b/java/org/apache/tomcat/dbcp/dbcp2/DriverFactory.java
index 82af50d..465418c 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/DriverFactory.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/DriverFactory.java
@@ -31,9 +31,9 @@ class DriverFactory {
     static Driver createDriver(final BasicDataSource basicDataSource) throws SQLException {
         // Load the JDBC driver class
         Driver driverToUse = basicDataSource.getDriver();
-        String driverClassName = basicDataSource.getDriverClassName();
-        ClassLoader driverClassLoader = basicDataSource.getDriverClassLoader();
-        String url = basicDataSource.getUrl();
+        final String driverClassName = basicDataSource.getDriverClassName();
+        final ClassLoader driverClassLoader = basicDataSource.getDriverClassLoader();
+        final String url = basicDataSource.getUrl();
 
         if (driverToUse == null) {
             Class<?> driverFromCCL = null;
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/Jdbc41Bridge.java b/java/org/apache/tomcat/dbcp/dbcp2/Jdbc41Bridge.java
index 0cb852a..15b943d 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/Jdbc41Bridge.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/Jdbc41Bridge.java
@@ -43,13 +43,19 @@ import javax.sql.CommonDataSource;
 /**
  * Defines bridge methods to JDBC 4.1 (Java 7) methods to allow call sites to operate safely (without
  * {@link AbstractMethodError}) when using a JDBC driver written for JDBC 4.0 (Java 6).
+ * <p>
+ * There should be no need to this kind of code for JDBC 4.2 in Java 8 due to JDBC's use of default methods.
+ * </p>
+ * <p>
+ * This should probably be moved or at least copied in some form to Apache Commons DbUtils.
+ * </p>
  *
  * @since 2.6.0
  */
 public class Jdbc41Bridge {
 
     /**
-     * Delegates to {@link Connection#abort(Executor)} without throwing a {@link AbstractMethodError}.
+     * Delegates to {@link Connection#abort(Executor)} without throwing an {@link AbstractMethodError}.
      * <p>
      * If the JDBC driver does not implement {@link Connection#abort(Executor)}, then call {@link Connection#close()}.
      * </p>
@@ -94,7 +100,7 @@ public class Jdbc41Bridge {
     }
 
     /**
-     * Delegates to {@link Connection#getNetworkTimeout()} without throwing a {@link AbstractMethodError}.
+     * Delegates to {@link Connection#getNetworkTimeout()} without throwing an {@link AbstractMethodError}.
      * <p>
      * If the JDBC driver does not implement {@link Connection#getNetworkTimeout()}, then return 0.
      * </p>
@@ -115,7 +121,7 @@ public class Jdbc41Bridge {
     }
 
     /**
-     * Delegates to {@link ResultSet#getObject(int, Class)} without throwing a {@link AbstractMethodError}.
+     * Delegates to {@link ResultSet#getObject(int, Class)} without throwing an {@link AbstractMethodError}.
      * <p>
      * If the JDBC driver does not implement {@link ResultSet#getObject(int, Class)}, then return 0.
      * </p>
@@ -215,7 +221,7 @@ public class Jdbc41Bridge {
     }
 
     /**
-     * Delegates to {@link ResultSet#getObject(String, Class)} without throwing a {@link AbstractMethodError}.
+     * Delegates to {@link ResultSet#getObject(String, Class)} without throwing an {@link AbstractMethodError}.
      *
      * @param <T>
      *            See {@link ResultSet#getObject(String, Class)}
@@ -343,7 +349,7 @@ public class Jdbc41Bridge {
     }
 
     /**
-     * Delegates to {@link Connection#getSchema()} without throwing a {@link AbstractMethodError}.
+     * Delegates to {@link Connection#getSchema()} without throwing an {@link AbstractMethodError}.
      * <p>
      * If the JDBC driver does not implement {@link Connection#getSchema()}, then return null.
      * </p>
@@ -365,7 +371,7 @@ public class Jdbc41Bridge {
     }
 
     /**
-     * Delegates to {@link Connection#setNetworkTimeout(Executor, int)} without throwing a {@link AbstractMethodError}.
+     * Delegates to {@link Connection#setNetworkTimeout(Executor, int)} without throwing an {@link AbstractMethodError}.
      * <p>
      * If the JDBC driver does not implement {@link Connection#setNetworkTimeout(Executor, int)}, then do nothing.
      * </p>
@@ -390,7 +396,7 @@ public class Jdbc41Bridge {
     }
 
     /**
-     * Delegates to {@link Connection#setSchema(String)} without throwing a {@link AbstractMethodError}.
+     * Delegates to {@link Connection#setSchema(String)} without throwing an {@link AbstractMethodError}.
      * <p>
      * If the JDBC driver does not implement {@link Connection#setSchema(String)}, then do nothing.
      * </p>
@@ -412,7 +418,7 @@ public class Jdbc41Bridge {
     }
 
     /**
-     * Delegates to {@link Statement#closeOnCompletion()} without throwing a {@link AbstractMethodError}.
+     * Delegates to {@link Statement#closeOnCompletion()} without throwing an {@link AbstractMethodError}.
      * <p>
      * If the JDBC driver does not implement {@link Statement#closeOnCompletion()}, then just check that the connection
      * is closed to then throw an SQLException.
@@ -435,7 +441,7 @@ public class Jdbc41Bridge {
     }
 
     /**
-     * Delegates to {@link Statement#isCloseOnCompletion()} without throwing a {@link AbstractMethodError}.
+     * Delegates to {@link Statement#isCloseOnCompletion()} without throwing an {@link AbstractMethodError}.
      * <p>
      * If the JDBC driver does not implement {@link Statement#isCloseOnCompletion()}, then just check that the
      * connection is closed to then throw an SQLException.
@@ -460,7 +466,7 @@ public class Jdbc41Bridge {
     }
 
     /**
-     * Delegates to {@link CommonDataSource#getParentLogger()} without throwing a {@link AbstractMethodError}.
+     * Delegates to {@link CommonDataSource#getParentLogger()} without throwing an {@link AbstractMethodError}.
      * <p>
      * If the JDBC driver does not implement {@link CommonDataSource#getParentLogger()}, then return null.
      * </p>
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/LifetimeExceededException.java b/java/org/apache/tomcat/dbcp/dbcp2/LifetimeExceededException.java
index 2d440cb..dd2bbdd 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/LifetimeExceededException.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/LifetimeExceededException.java
@@ -29,7 +29,6 @@ class LifetimeExceededException extends Exception {
      * Create a LifetimeExceededException.
      */
     public LifetimeExceededException() {
-        super();
     }
 
     /**
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/ObjectNameWrapper.java b/java/org/apache/tomcat/dbcp/dbcp2/ObjectNameWrapper.java
index 9c78936..ec68460 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/ObjectNameWrapper.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/ObjectNameWrapper.java
@@ -36,12 +36,12 @@ class ObjectNameWrapper {
 
     private static final Log log = LogFactory.getLog(ObjectNameWrapper.class);
 
-    private static MBeanServer MBEAN_SERVER = getPlatformMBeanServer();
+    private static final MBeanServer MBEAN_SERVER = getPlatformMBeanServer();
 
     private static MBeanServer getPlatformMBeanServer() {
         try {
             return ManagementFactory.getPlatformMBeanServer();
-        } catch (LinkageError | Exception e) {
+        } catch (final LinkageError | Exception e) {
             // ignore - JMX not available
             log.debug("Failed to get platform MBeanServer", e);
             return null;
@@ -72,7 +72,7 @@ class ObjectNameWrapper {
         }
         try {
             MBEAN_SERVER.registerMBean(object, objectName);
-        } catch (LinkageError | Exception e) {
+        } catch (final LinkageError | Exception e) {
             log.warn("Failed to complete JMX registration for " + objectName, e);
         }
     }
@@ -92,7 +92,7 @@ class ObjectNameWrapper {
         if (MBEAN_SERVER.isRegistered(objectName)) {
             try {
                 MBEAN_SERVER.unregisterMBean(objectName);
-            } catch (LinkageError | Exception e) {
+            } catch (final LinkageError | Exception e) {
                 log.warn("Failed to complete JMX unregistration for " + objectName, e);
             }
         }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/PStmtKey.java b/java/org/apache/tomcat/dbcp/dbcp2/PStmtKey.java
index 39d149a..3b5daf3 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/PStmtKey.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/PStmtKey.java
@@ -20,6 +20,7 @@ import java.sql.Connection;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.Arrays;
+import java.util.Objects;
 
 import org.apache.tomcat.dbcp.dbcp2.PoolingConnection.StatementType;
 
@@ -56,8 +57,7 @@ public class PStmtKey {
     private class PreparedCallWithResultSetHoldability implements StatementBuilder {
         @Override
         public Statement createStatement(final Connection connection) throws SQLException {
-            return connection.prepareCall(sql, resultSetType.intValue(), resultSetConcurrency.intValue(),
-                    resultSetHoldability.intValue());
+            return connection.prepareCall(sql, resultSetType.intValue(), resultSetConcurrency.intValue(), resultSetHoldability.intValue());
         }
     }
 
@@ -117,8 +117,7 @@ public class PStmtKey {
     private class PreparedStatementWithResultSetHoldability implements StatementBuilder {
         @Override
         public Statement createStatement(final Connection connection) throws SQLException {
-            return connection.prepareStatement(sql, resultSetType.intValue(), resultSetConcurrency.intValue(),
-                    resultSetHoldability.intValue());
+            return connection.prepareStatement(sql, resultSetType.intValue(), resultSetConcurrency.intValue(), resultSetHoldability.intValue());
         }
     }
 
@@ -798,18 +797,10 @@ public class PStmtKey {
             return false;
         }
         final PStmtKey other = (PStmtKey) obj;
-        if (autoGeneratedKeys == null) {
-            if (other.autoGeneratedKeys != null) {
-                return false;
-            }
-        } else if (!autoGeneratedKeys.equals(other.autoGeneratedKeys)) {
+        if (!Objects.equals(autoGeneratedKeys, other.autoGeneratedKeys)) {
             return false;
         }
-        if (catalog == null) {
-            if (other.catalog != null) {
-                return false;
-            }
-        } else if (!catalog.equals(other.catalog)) {
+        if (!Objects.equals(catalog, other.catalog)) {
             return false;
         }
         if (!Arrays.equals(columnIndexes, other.columnIndexes)) {
@@ -818,45 +809,22 @@ public class PStmtKey {
         if (!Arrays.equals(columnNames, other.columnNames)) {
             return false;
         }
-        if (resultSetConcurrency == null) {
-            if (other.resultSetConcurrency != null) {
-                return false;
-            }
-        } else if (!resultSetConcurrency.equals(other.resultSetConcurrency)) {
+        if (!Objects.equals(resultSetConcurrency, other.resultSetConcurrency)) {
             return false;
         }
-        if (resultSetHoldability == null) {
-            if (other.resultSetHoldability != null) {
-                return false;
-            }
-        } else if (!resultSetHoldability.equals(other.resultSetHoldability)) {
+        if (!Objects.equals(resultSetHoldability, other.resultSetHoldability)) {
             return false;
         }
-        if (resultSetType == null) {
-            if (other.resultSetType != null) {
-                return false;
-            }
-        } else if (!resultSetType.equals(other.resultSetType)) {
+        if (!Objects.equals(resultSetType, other.resultSetType)) {
             return false;
         }
-        if (schema == null) {
-            if (other.schema != null) {
-                return false;
-            }
-        } else if (!schema.equals(other.schema)) {
+        if (!Objects.equals(schema, other.schema)) {
             return false;
         }
-        if (sql == null) {
-            if (other.sql != null) {
-                return false;
-            }
-        } else if (!sql.equals(other.sql)) {
+        if (!Objects.equals(sql, other.sql)) {
             return false;
         }
-        if (statementType != other.statementType) {
-            return false;
-        }
-        return true;
+        return statementType == other.statementType;
     }
 
     /**
@@ -955,24 +923,13 @@ public class PStmtKey {
 
     @Override
     public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((autoGeneratedKeys == null) ? 0 : autoGeneratedKeys.hashCode());
-        result = prime * result + ((catalog == null) ? 0 : catalog.hashCode());
-        result = prime * result + Arrays.hashCode(columnIndexes);
-        result = prime * result + Arrays.hashCode(columnNames);
-        result = prime * result + ((resultSetConcurrency == null) ? 0 : resultSetConcurrency.hashCode());
-        result = prime * result + ((resultSetHoldability == null) ? 0 : resultSetHoldability.hashCode());
-        result = prime * result + ((resultSetType == null) ? 0 : resultSetType.hashCode());
-        result = prime * result + ((schema == null) ? 0 : schema.hashCode());
-        result = prime * result + ((sql == null) ? 0 : sql.hashCode());
-        result = prime * result + ((statementType == null) ? 0 : statementType.hashCode());
-        return result;
+        return Objects.hash(autoGeneratedKeys, catalog, Integer.valueOf(Arrays.hashCode(columnIndexes)), Integer.valueOf(Arrays.hashCode(columnNames)),
+            resultSetConcurrency, resultSetHoldability, resultSetType, schema, sql, statementType);
     }
 
     @Override
     public String toString() {
-        final StringBuffer buf = new StringBuffer();
+        final StringBuilder buf = new StringBuilder();
         buf.append("PStmtKey: sql=");
         buf.append(sql);
         buf.append(", catalog=");
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/PoolableCallableStatement.java b/java/org/apache/tomcat/dbcp/dbcp2/PoolableCallableStatement.java
index f8456980..5057701 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/PoolableCallableStatement.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/PoolableCallableStatement.java
@@ -121,12 +121,12 @@ public class PoolableCallableStatement extends DelegatingCallableStatement {
         final List<AbandonedTrace> resultSetList = getTrace();
         if (resultSetList != null) {
             final List<Exception> thrownList = new ArrayList<>();
-            final ResultSet[] resultSets = resultSetList.toArray(new ResultSet[0]);
+            final ResultSet[] resultSets = resultSetList.toArray(Utils.EMPTY_RESULT_SET_ARRAY);
             for (final ResultSet resultSet : resultSets) {
                 if (resultSet != null) {
                     try {
                         resultSet.close();
-                    } catch (Exception e) {
+                    } catch (final Exception e) {
                         thrownList.add(e);
                     }
                 }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnection.java b/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnection.java
index bdca159..6b052ce 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnection.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnection.java
@@ -22,6 +22,7 @@ import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.Collection;
+import java.util.concurrent.Executor;
 
 import javax.management.InstanceAlreadyExistsException;
 import javax.management.MBeanRegistrationException;
@@ -44,7 +45,7 @@ public class PoolableConnection extends DelegatingConnection<Connection> impleme
     static {
         try {
             MBEAN_SERVER = ManagementFactory.getPlatformMBeanServer();
-        } catch (NoClassDefFoundError | Exception ex) {
+        } catch (final NoClassDefFoundError | Exception ex) {
             // ignore - JMX not available
         }
     }
@@ -205,9 +206,7 @@ public class PoolableConnection extends DelegatingConnection<Connection> impleme
                 // pool is closed, so close the connection
                 passivate();
                 getInnermostDelegate().close();
-            } catch (final SQLException e) {
-                throw e;
-            } catch (final RuntimeException e) {
+            } catch (final SQLException | RuntimeException e) {
                 throw e;
             } catch (final Exception e) {
                 throw new SQLException("Cannot close connection (return to pool failed)", e);
@@ -236,6 +235,19 @@ public class PoolableConnection extends DelegatingConnection<Connection> impleme
     }
 
     /**
+     * Abort my underlying {@link Connection}.
+     *
+     * @since 2.9.0
+     */
+    @Override
+    public void abort(Executor executor) throws SQLException {
+        if (jmxObjectName != null) {
+            jmxObjectName.unregisterMBean();
+        }
+        super.abort(executor);
+    }
+
+    /**
      * Expose the {@link #toString()} method via a bean getter so it can be read as a property via JMX.
      */
     @Override
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionFactory.java b/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionFactory.java
index b25bb9a..97d1897 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionFactory.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionFactory.java
@@ -28,6 +28,7 @@ import javax.management.ObjectName;
 
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.dbcp.pool2.DestroyMode;
 import org.apache.tomcat.dbcp.pool2.KeyedObjectPool;
 import org.apache.tomcat.dbcp.pool2.ObjectPool;
 import org.apache.tomcat.dbcp.pool2.PooledObject;
@@ -140,6 +141,14 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
     }
 
     /**
+     * @since 2.9.0
+     */
+    @Override
+    public void destroyObject(final PooledObject<PoolableConnection> p, final DestroyMode mode) throws Exception {
+        destroyObject(p);
+    }
+
+    /**
      * @return The cache state.
      * @since Made public in 2.6.0.
      */
@@ -269,7 +278,6 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
     protected int getMaxOpenPreparedStatements() {
         return maxOpenPreparedStatements;
     }
-
     /**
      * Returns the {@link ObjectPool} in which {@link Connection}s are pooled.
      *
@@ -278,7 +286,6 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
     public synchronized ObjectPool<PoolableConnection> getPool() {
         return pool;
     }
-
     /**
      * @return Whether to pool statements.
      * @since Made public in 2.6.0.
@@ -293,6 +300,7 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
     public String getValidationQuery() {
         return validationQuery;
     }
+
     /**
      * @return Validation query timeout in seconds.
      * @since 2.6.0
@@ -300,6 +308,7 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
     public int getValidationQueryTimeoutSeconds() {
         return validationQueryTimeoutSeconds;
     }
+
     protected void initializeConnection(final Connection conn) throws SQLException {
         final Collection<String> sqls = connectionInitSqls;
         if (conn.isClosed()) {
@@ -384,7 +393,7 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
             if (dataSourceJmxObjectName != null) {
                 final StringBuilder base = new StringBuilder(dataSourceJmxObjectName.toString());
                 base.append(Constants.JMX_CONNECTION_BASE_EXT);
-                base.append(Long.toString(connIndex));
+                base.append(connIndex);
                 config.setJmxNameBase(base.toString());
                 config.setJmxNamePrefix(Constants.JMX_STATEMENT_POOL_PREFIX);
             } else {
@@ -399,7 +408,7 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
         }
 
         // Register this connection with JMX
-        ObjectName connJmxName;
+        final ObjectName connJmxName;
         if (dataSourceJmxObjectName == null) {
             connJmxName = null;
         } else {
@@ -453,6 +462,17 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
     }
 
     /**
+     * Sets whether the pool of statements (which was enabled with {@link #setPoolStatements(boolean)}) should
+     * be cleared when the connection is returned to its pool. Default is false.
+     *
+     * @param clearStatementPoolOnReturn clear or not
+     * @since 2.8.0
+     */
+    public void setClearStatementPoolOnReturn(final boolean clearStatementPoolOnReturn) {
+        this.clearStatementPoolOnReturn = clearStatementPoolOnReturn;
+    }
+
+    /**
      * Sets the SQL statements I use to initialize newly created {@link Connection}s. Using {@code null} turns off
      * connection initialization.
      *
@@ -462,7 +482,6 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
     public void setConnectionInitSql(final Collection<String> connectionInitSqls) {
         this.connectionInitSqls = connectionInitSqls;
     }
-
     /**
      * Sets the default "auto commit" setting for borrowed {@link Connection}s
      *
@@ -486,6 +505,7 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
     public void setDefaultQueryTimeout(final Integer defaultQueryTimeoutSeconds) {
         this.defaultQueryTimeoutSeconds = defaultQueryTimeoutSeconds;
     }
+
     /**
      * Sets the default "read only" setting for borrowed {@link Connection}s
      *
@@ -600,17 +620,6 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
         this.poolStatements = poolStatements;
     }
 
-    /**
-     * Sets whether the pool of statements (which was enabled with {@link #setPoolStatements(boolean)}) should
-     * be cleared when the connection is returned to its pool. Default is false.
-     *
-     * @param clearStatementPoolOnReturn clear or not
-     * @since 2.8.0
-     */
-    public void setClearStatementPoolOnReturn(final boolean clearStatementPoolOnReturn) {
-        this.clearStatementPoolOnReturn = clearStatementPoolOnReturn;
-    }
-
     public void setRollbackOnReturn(final boolean rollbackOnReturn) {
         this.rollbackOnReturn = rollbackOnReturn;
     }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/PoolablePreparedStatement.java b/java/org/apache/tomcat/dbcp/dbcp2/PoolablePreparedStatement.java
index 0da2fab..765213d 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/PoolablePreparedStatement.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/PoolablePreparedStatement.java
@@ -102,9 +102,7 @@ public class PoolablePreparedStatement<K> extends DelegatingPreparedStatement {
         if (!isClosed()) {
             try {
                 pool.returnObject(key, this);
-            } catch (final SQLException e) {
-                throw e;
-            } catch (final RuntimeException e) {
+            } catch (final SQLException | RuntimeException e) {
                 throw e;
             } catch (final Exception e) {
                 throw new SQLException("Cannot close preparedstatement (return to pool failed)", e);
@@ -138,12 +136,12 @@ public class PoolablePreparedStatement<K> extends DelegatingPreparedStatement {
         final List<AbandonedTrace> resultSetList = getTrace();
         if (resultSetList != null) {
             final List<Exception> thrownList = new ArrayList<>();
-            final ResultSet[] resultSets = resultSetList.toArray(new ResultSet[0]);
+            final ResultSet[] resultSets = resultSetList.toArray(Utils.EMPTY_RESULT_SET_ARRAY);
             for (final ResultSet resultSet : resultSets) {
                 if (resultSet != null) {
                     try {
                         resultSet.close();
-                    } catch (Exception e) {
+                    } catch (final Exception e) {
                         thrownList.add(e);
                     }
                 }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java b/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java
index 6dd738f..f029a28 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java
@@ -23,6 +23,7 @@ import java.sql.PreparedStatement;
 import java.sql.SQLException;
 import java.util.NoSuchElementException;
 
+import org.apache.tomcat.dbcp.pool2.DestroyMode;
 import org.apache.tomcat.dbcp.pool2.KeyedObjectPool;
 import org.apache.tomcat.dbcp.pool2.KeyedPooledObjectFactory;
 import org.apache.tomcat.dbcp.pool2.PooledObject;
@@ -129,7 +130,7 @@ public class PoolingConnection extends DelegatingConnection<Connection>
         if (pstmtPool != null && clearStatementPoolOnReturn) {
             try {
                 pstmtPool.clear();
-            } catch (Exception e) {
+            } catch (final Exception e) {
                 throw new SQLException("Error clearing statement pool", e);
             }
         }
@@ -158,7 +159,7 @@ public class PoolingConnection extends DelegatingConnection<Connection>
      *
      * @return the PStmtKey created for the given arguments.
      */
-    protected PStmtKey createKey(final String sql, final int columnIndexes[]) {
+    protected PStmtKey createKey(final String sql, final int[] columnIndexes) {
         return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), getSchemaOrNull(), columnIndexes);
     }
 
@@ -278,7 +279,7 @@ public class PoolingConnection extends DelegatingConnection<Connection>
      *
      * @return the PStmtKey created for the given arguments.
      */
-    protected PStmtKey createKey(final String sql, final String columnNames[]) {
+    protected PStmtKey createKey(final String sql, final String[] columnNames) {
         return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), getSchemaOrNull(), columnNames);
     }
 
@@ -297,6 +298,12 @@ public class PoolingConnection extends DelegatingConnection<Connection>
         pooledObject.getObject().getInnermostDelegate().close();
     }
 
+    @Override
+    public void destroyObject(PStmtKey key, PooledObject<DelegatingPreparedStatement> p,
+            DestroyMode mode) throws Exception {
+        destroyObject(key, p);
+    }
+
     private String getCatalogOrNull() {
         String catalog = null;
         try {
@@ -517,7 +524,7 @@ public class PoolingConnection extends DelegatingConnection<Connection>
      *
      */
     @Override
-    public PreparedStatement prepareStatement(final String sql, final int columnIndexes[]) throws SQLException {
+    public PreparedStatement prepareStatement(final String sql, final int[] columnIndexes) throws SQLException {
         return prepareStatement(createKey(sql, columnIndexes));
     }
 
@@ -573,7 +580,7 @@ public class PoolingConnection extends DelegatingConnection<Connection>
      *             Wraps an underlying exception.
      */
     @Override
-    public PreparedStatement prepareStatement(final String sql, final String columnNames[]) throws SQLException {
+    public PreparedStatement prepareStatement(final String sql, final String[] columnNames) throws SQLException {
         return prepareStatement(createKey(sql, columnNames));
     }
 
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/PoolingDataSource.java b/java/org/apache/tomcat/dbcp/dbcp2/PoolingDataSource.java
index 38a0472..5f0ca20 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/PoolingDataSource.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/PoolingDataSource.java
@@ -136,11 +136,9 @@ public class PoolingDataSource<C extends Connection> implements DataSource, Auto
                 return null;
             }
             return new PoolGuardConnectionWrapper<>(conn);
-        } catch (final SQLException e) {
-            throw e;
         } catch (final NoSuchElementException e) {
             throw new SQLException("Cannot get a connection, pool error " + e.getMessage(), e);
-        } catch (final RuntimeException e) {
+        } catch (final SQLException | RuntimeException e) {
             throw e;
         } catch (final InterruptedException e) {
             // Reset the interrupt status so it is visible to callers
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/PoolingDriver.java b/java/org/apache/tomcat/dbcp/dbcp2/PoolingDriver.java
index bf9b97a..67b4c4d 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/PoolingDriver.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/PoolingDriver.java
@@ -25,7 +25,6 @@ import java.sql.SQLFeatureNotSupportedException;
 import java.util.HashMap;
 import java.util.NoSuchElementException;
 import java.util.Properties;
-import java.util.Set;
 import java.util.logging.Logger;
 
 import org.apache.tomcat.dbcp.pool2.ObjectPool;
@@ -37,7 +36,9 @@ import org.apache.tomcat.dbcp.pool2.ObjectPool;
  */
 public class PoolingDriver implements Driver {
 
-    /** Register myself with the {@link DriverManager}. */
+    private static final DriverPropertyInfo[] EMPTY_DRIVER_PROPERTY_INFO_ARRAY = new DriverPropertyInfo[0];
+
+    /* Register myself with the {@link DriverManager}. */
     static {
         try {
             DriverManager.registerDriver(new PoolingDriver());
@@ -133,13 +134,12 @@ public class PoolingDriver implements Driver {
      * @return the pool names.
      */
     public synchronized String[] getPoolNames() {
-        final Set<String> names = pools.keySet();
-        return names.toArray(new String[0]);
+        return pools.keySet().toArray(Utils.EMPTY_STRING_ARRAY);
     }
 
     @Override
     public boolean acceptsURL(final String url) throws SQLException {
-        return url == null ? false : url.startsWith(URL_PREFIX);
+        return url != null && url.startsWith(URL_PREFIX);
     }
 
     @Override
@@ -153,11 +153,9 @@ public class PoolingDriver implements Driver {
                     return null;
                 }
                 return new PoolGuardConnectionWrapper(pool, conn);
-            } catch (final SQLException e) {
-                throw e;
             } catch (final NoSuchElementException e) {
                 throw new SQLException("Cannot get a connection, pool error: " + e.getMessage(), e);
-            } catch (final RuntimeException e) {
+            } catch (final SQLException | RuntimeException e) {
                 throw e;
             } catch (final Exception e) {
                 throw new SQLException("Cannot get a connection, general error: " + e.getMessage(), e);
@@ -212,7 +210,7 @@ public class PoolingDriver implements Driver {
 
     @Override
     public DriverPropertyInfo[] getPropertyInfo(final String url, final Properties info) {
-        return new DriverPropertyInfo[0];
+        return EMPTY_DRIVER_PROPERTY_INFO_ARRAY;
     }
 
     /** My URL prefix */
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/SQLExceptionList.java b/java/org/apache/tomcat/dbcp/dbcp2/SQLExceptionList.java
index 3f8d1af..a8392b2 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/SQLExceptionList.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/SQLExceptionList.java
@@ -39,7 +39,7 @@ public class SQLExceptionList extends SQLException {
      *
      * @param causeList a list of cause exceptions.
      */
-    public SQLExceptionList(List<? extends Throwable> causeList) {
+    public SQLExceptionList(final List<? extends Throwable> causeList) {
         super(String.format("%,d exceptions: %s", Integer.valueOf(causeList == null ? 0 : causeList.size()), causeList),
                 causeList == null ? null : causeList.get(0));
         this.causeList = causeList;
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/Utils.java b/java/org/apache/tomcat/dbcp/dbcp2/Utils.java
index a24360f..ce497ff 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/Utils.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/Utils.java
@@ -18,8 +18,10 @@
 
 package org.apache.tomcat.dbcp.dbcp2;
 
+import java.sql.ResultSet;
 import java.text.MessageFormat;
 import java.util.HashSet;
+import java.util.Properties;
 import java.util.ResourceBundle;
 import java.util.Set;
 
@@ -31,7 +33,7 @@ import java.util.Set;
 public final class Utils {
 
     private static final ResourceBundle messages = ResourceBundle
-            .getBundle(Utils.class.getPackage().getName() + ".LocalStrings");
+        .getBundle(Utils.class.getPackage().getName() + ".LocalStrings");
 
     /**
      * Whether the security manager is enabled.
@@ -54,6 +56,9 @@ public final class Utils {
      */
     public static final Set<String> DISCONNECTION_SQL_CODES;
 
+    static final ResultSet[] EMPTY_RESULT_SET_ARRAY = new ResultSet[0];
+    static final String[] EMPTY_STRING_ARRAY = new String[0];
+
     static {
         DISCONNECTION_SQL_CODES = new HashSet<>();
         DISCONNECTION_SQL_CODES.add("57P01"); // Admin shutdown
@@ -67,8 +72,7 @@ public final class Utils {
     /**
      * Clones the given char[] if not null.
      *
-     * @param value
-     *            may be null.
+     * @param value may be null.
      * @return a cloned char[] or null.
      */
     public static char[] clone(final char[] value) {
@@ -76,10 +80,26 @@ public final class Utils {
     }
 
     /**
+     * Clones the given {@link Properties} without the standard "user" or "password" entries.
+     *
+     * @param properties may be null
+     * @return a clone of the input without the standard "user" or "password" entries.
+     * @since 2.8.0
+     */
+    public static Properties cloneWithoutCredentials(final Properties properties) {
+        if (properties != null) {
+            final Properties temp = (Properties) properties.clone();
+            temp.remove("user");
+            temp.remove("password");
+            return temp;
+        }
+        return properties;
+    }
+
+    /**
      * Closes the AutoCloseable (which may be null).
      *
-     * @param autoCloseable
-     *            an AutoCloseable, may be {@code null}
+     * @param autoCloseable an AutoCloseable, may be {@code null}
      * @since 2.6.0
      */
     public static void closeQuietly(final AutoCloseable autoCloseable) {
@@ -95,8 +115,7 @@ public final class Utils {
     /**
      * Gets the correct i18n message for the given key.
      *
-     * @param key
-     *            The key to look up an i18n message.
+     * @param key The key to look up an i18n message.
      * @return The i18n message.
      */
     public static String getMessage(final String key) {
@@ -106,10 +125,8 @@ public final class Utils {
     /**
      * Gets the correct i18n message for the given key with placeholders replaced by the supplied arguments.
      *
-     * @param key
-     *            A message key.
-     * @param args
-     *            The message arguments.
+     * @param key A message key.
+     * @param args The message arguments.
      * @return An i18n message.
      */
     public static String getMessage(final String key, final Object... args) {
@@ -124,8 +141,7 @@ public final class Utils {
     /**
      * Converts the given String to a char[].
      *
-     * @param value
-     *            may be null.
+     * @param value may be null.
      * @return a char[] or null.
      */
     public static char[] toCharArray(final String value) {
@@ -135,8 +151,7 @@ public final class Utils {
     /**
      * Converts the given char[] to a String.
      *
-     * @param value
-     *            may be null.
+     * @param value may be null.
      * @return a String or null.
      */
     public static String toString(final char[] value) {
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/ConnectionImpl.java b/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/ConnectionImpl.java
index ca6498a..720c36b 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/ConnectionImpl.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/ConnectionImpl.java
@@ -242,7 +242,7 @@ class ConnectionImpl extends DelegatingConnection<Connection> {
     }
 
     @Override
-    public PreparedStatement prepareStatement(final String sql, final int columnIndexes[]) throws SQLException {
+    public PreparedStatement prepareStatement(final String sql, final int[] columnIndexes) throws SQLException {
         checkOpen();
         try {
             return new DelegatingPreparedStatement(this, pooledConnection.prepareStatement(sql, columnIndexes));
@@ -253,7 +253,7 @@ class ConnectionImpl extends DelegatingConnection<Connection> {
     }
 
     @Override
-    public PreparedStatement prepareStatement(final String sql, final String columnNames[]) throws SQLException {
+    public PreparedStatement prepareStatement(final String sql, final String[] columnNames) throws SQLException {
         checkOpen();
         try {
             return new DelegatingPreparedStatement(this, pooledConnection.prepareStatement(sql, columnNames));
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java b/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java
index 772682f..b912ba6 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java
@@ -85,7 +85,7 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
     private static final long serialVersionUID = -4820523787212147844L;
 
     private static final String GET_CONNECTION_CALLED = "A PooledConnection was already requested from this source, "
-            + "further initialization is not allowed.";
+        + "further initialization is not allowed.";
 
     static {
         // Attempt to prevent deadlocks - see DBCP - 272
@@ -147,8 +147,8 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
         }
     }
 
-    private boolean getBooleanContentString(RefAddr ra) {
-        return Boolean.valueOf(getStringContent(ra)).booleanValue();
+    private boolean getBooleanContentString(final RefAddr ra) {
+        return Boolean.parseBoolean(getStringContent(ra));
     }
 
     /**
@@ -248,7 +248,7 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
      */
     @Override
     public Object getObjectInstance(final Object refObj, final Name name, final Context context,
-            final Hashtable<?, ?> env) throws Exception {
+        final Hashtable<?, ?> env) throws Exception {
         // The spec says to return null if we can't create an instance
         // of the reference
         DriverAdapterCPDS cpds = null;
@@ -351,14 +351,12 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
     /**
      * Attempts to establish a database connection.
      *
-     * @param pooledUserName
-     *            name to be used for the connection
-     * @param pooledUserPassword
-     *            password to be used fur the connection
+     * @param pooledUserName name to be used for the connection
+     * @param pooledUserPassword password to be used fur the connection
      */
     @Override
     public PooledConnection getPooledConnection(final String pooledUserName, final String pooledUserPassword)
-            throws SQLException {
+        throws SQLException {
         getConnectionCalled = true;
         PooledConnectionImpl pooledConnection = null;
         // Workaround for buggy WebLogic 5.1 classloader - ignore the exception upon first invocation.
@@ -367,19 +365,19 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
                 update(connectionProperties, KEY_USER, pooledUserName);
                 update(connectionProperties, KEY_PASSWORD, pooledUserPassword);
                 pooledConnection = new PooledConnectionImpl(
-                        DriverManager.getConnection(getUrl(), connectionProperties));
+                    DriverManager.getConnection(getUrl(), connectionProperties));
             } else {
                 pooledConnection = new PooledConnectionImpl(
-                        DriverManager.getConnection(getUrl(), pooledUserName, pooledUserPassword));
+                    DriverManager.getConnection(getUrl(), pooledUserName, pooledUserPassword));
             }
             pooledConnection.setAccessToUnderlyingConnectionAllowed(isAccessToUnderlyingConnectionAllowed());
         } catch (final ClassCircularityError e) {
             if (connectionProperties != null) {
                 pooledConnection = new PooledConnectionImpl(
-                        DriverManager.getConnection(getUrl(), connectionProperties));
+                    DriverManager.getConnection(getUrl(), connectionProperties));
             } else {
                 pooledConnection = new PooledConnectionImpl(
-                        DriverManager.getConnection(getUrl(), pooledUserName, pooledUserPassword));
+                    DriverManager.getConnection(getUrl(), pooledUserName, pooledUserPassword));
             }
             pooledConnection.setAccessToUnderlyingConnectionAllowed(isAccessToUnderlyingConnectionAllowed());
         }
@@ -438,7 +436,7 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
         return ref;
     }
 
-    private String getStringContent(RefAddr ra) {
+    private String getStringContent(final RefAddr ra) {
         return ra.getContent().toString();
     }
 
@@ -480,7 +478,7 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
         return this.accessToUnderlyingConnectionAllowed;
     }
 
-    private boolean isNotEmpty(RefAddr ra) {
+    private boolean isNotEmpty(final RefAddr ra) {
         return ra != null && ra.getContent() != null;
     }
 
@@ -497,8 +495,7 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
      * Sets the value of the accessToUnderlyingConnectionAllowed property. It controls if the PoolGuard allows access to
      * the underlying connection. (Default: false)
      *
-     * @param allow
-     *            Access to the underlying connection is granted when true.
+     * @param allow Access to the underlying connection is granted when true.
      */
     public synchronized void setAccessToUnderlyingConnectionAllowed(final boolean allow) {
         this.accessToUnderlyingConnectionAllowed = allow;
@@ -515,10 +512,8 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
      * null.
      * </p>
      *
-     * @param props
-     *            Connection properties to use when creating new connections.
-     * @throws IllegalStateException
-     *             if {@link #getPooledConnection()} has been called
+     * @param props Connection properties to use when creating new connections.
+     * @throws IllegalStateException if {@link #getPooledConnection()} has been called
      */
     public void setConnectionProperties(final Properties props) {
         assertInitializationAllowed();
@@ -537,8 +532,7 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
      * Sets the value of description. This property is here for use by the code which will deploy this datasource. It is
      * not used internally.
      *
-     * @param v
-     *            Value to assign to description.
+     * @param v Value to assign to description.
      */
     public void setDescription(final String v) {
         this.description = v;
@@ -548,12 +542,9 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
      * Sets the driver class name. Setting the driver class name cause the driver to be registered with the
      * DriverManager.
      *
-     * @param v
-     *            Value to assign to driver.
-     * @throws IllegalStateException
-     *             if {@link #getPooledConnection()} has been called
-     * @throws ClassNotFoundException
-     *             if the class cannot be located
+     * @param v Value to assign to driver.
+     * @throws IllegalStateException if {@link #getPooledConnection()} has been called
+     * @throws ClassNotFoundException if the class cannot be located
      */
     public void setDriver(final String v) throws ClassNotFoundException {
         assertInitializationAllowed();
@@ -583,10 +574,8 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
      * Gets the maximum number of statements that can remain idle in the pool, without extra ones being released, or
      * negative for no limit.
      *
-     * @param maxIdle
-     *            The maximum number of statements that can remain idle
-     * @throws IllegalStateException
-     *             if {@link #getPooledConnection()} has been called
+     * @param maxIdle The maximum number of statements that can remain idle
+     * @throws IllegalStateException if {@link #getPooledConnection()} has been called
      */
     public void setMaxIdle(final int maxIdle) {
         assertInitializationAllowed();
@@ -596,8 +585,7 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
     /**
      * Sets the maximum number of prepared statements.
      *
-     * @param maxPreparedStatements
-     *            the new maximum number of prepared statements
+     * @param maxPreparedStatements the new maximum number of prepared statements
      */
     public void setMaxPreparedStatements(final int maxPreparedStatements) {
         this.maxPreparedStatements = maxPreparedStatements;
@@ -607,12 +595,10 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
      * Sets the minimum amount of time a statement may sit idle in the pool before it is eligible for eviction by the
      * idle object evictor (if any). When non-positive, no objects will be evicted from the pool due to idle time alone.
      *
-     * @param minEvictableIdleTimeMillis
-     *            minimum time to set (in ms)
+     * @param minEvictableIdleTimeMillis minimum time to set (in ms)
      * @see #getMinEvictableIdleTimeMillis()
      * @see #setTimeBetweenEvictionRunsMillis(long)
-     * @throws IllegalStateException
-     *             if {@link #getPooledConnection()} has been called
+     * @throws IllegalStateException if {@link #getPooledConnection()} has been called
      */
     public void setMinEvictableIdleTimeMillis(final int minEvictableIdleTimeMillis) {
         assertInitializationAllowed();
@@ -640,10 +626,8 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
     /**
      * Sets the value of password for the default user.
      *
-     * @param userPassword
-     *            Value to assign to password.
-     * @throws IllegalStateException
-     *             if {@link #getPooledConnection()} has been called
+     * @param userPassword Value to assign to password.
+     * @throws IllegalStateException if {@link #getPooledConnection()} has been called
      */
     public void setPassword(final char[] userPassword) {
         assertInitializationAllowed();
@@ -654,10 +638,8 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
     /**
      * Sets the value of password for the default user.
      *
-     * @param userPassword
-     *            Value to assign to password.
-     * @throws IllegalStateException
-     *             if {@link #getPooledConnection()} has been called
+     * @param userPassword Value to assign to password.
+     * @throws IllegalStateException if {@link #getPooledConnection()} has been called
      */
     public void setPassword(final String userPassword) {
         assertInitializationAllowed();
@@ -668,10 +650,8 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
     /**
      * Whether to toggle the pooling of <code>PreparedStatement</code>s
      *
-     * @param poolPreparedStatements
-     *            true to pool statements.
-     * @throws IllegalStateException
-     *             if {@link #getPooledConnection()} has been called
+     * @param poolPreparedStatements true to pool statements.
+     * @throws IllegalStateException if {@link #getPooledConnection()} has been called
      */
     public void setPoolPreparedStatements(final boolean poolPreparedStatements) {
         assertInitializationAllowed();
@@ -682,12 +662,10 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
      * Sets the number of milliseconds to sleep between runs of the idle object evictor thread. When non-positive, no
      * idle object evictor thread will be run.
      *
-     * @param timeBetweenEvictionRunsMillis
-     *            The number of milliseconds to sleep between runs of the idle object evictor thread. When non-positive,
-     *            no idle object evictor thread will be run.
+     * @param timeBetweenEvictionRunsMillis The number of milliseconds to sleep between runs of the idle object evictor
+     *        thread. When non-positive, no idle object evictor thread will be run.
      * @see #getTimeBetweenEvictionRunsMillis()
-     * @throws IllegalStateException
-     *             if {@link #getPooledConnection()} has been called
+     * @throws IllegalStateException if {@link #getPooledConnection()} has been called
      */
     public void setTimeBetweenEvictionRunsMillis(final long timeBetweenEvictionRunsMillis) {
         assertInitializationAllowed();
@@ -697,10 +675,8 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
     /**
      * Sets the value of URL string used to locate the database for this datasource.
      *
-     * @param v
-     *            Value to assign to url.
-     * @throws IllegalStateException
-     *             if {@link #getPooledConnection()} has been called
+     * @param v Value to assign to url.
+     * @throws IllegalStateException if {@link #getPooledConnection()} has been called
      */
     public void setUrl(final String v) {
         assertInitializationAllowed();
@@ -710,10 +686,8 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
     /**
      * Sets the value of default user (login or user name).
      *
-     * @param v
-     *            Value to assign to user.
-     * @throws IllegalStateException
-     *             if {@link #getPooledConnection()} has been called
+     * @param v Value to assign to user.
+     * @throws IllegalStateException if {@link #getPooledConnection()} has been called
      */
     public void setUser(final String v) {
         assertInitializationAllowed();
@@ -732,7 +706,8 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
         builder.append("[description=");
         builder.append(description);
         builder.append(", url=");
-        // TODO What if the connection string contains a 'user' or 'password' query parameter but that connection string is not in a legal URL format?
+        // TODO What if the connection string contains a 'user' or 'password' query parameter but that connection string
+        // is not in a legal URL format?
         builder.append(url);
         builder.append(", driver=");
         builder.append(driver);
@@ -753,24 +728,13 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
         builder.append(", getConnectionCalled=");
         builder.append(getConnectionCalled);
         builder.append(", connectionProperties=");
-        Properties tmpProps = connectionProperties;
-        tmpProps = mask(tmpProps, "user");
-        tmpProps = mask(tmpProps, "password");
-        builder.append(tmpProps);
+        builder.append(Utils.cloneWithoutCredentials(connectionProperties));
         builder.append(", accessToUnderlyingConnectionAllowed=");
         builder.append(accessToUnderlyingConnectionAllowed);
         builder.append("]");
         return builder.toString();
     }
 
-    private Properties mask(Properties properties, final String maskValueAtKey) {
-        if (connectionProperties != null && connectionProperties.contains(maskValueAtKey)) {
-            properties = (Properties) connectionProperties.clone();
-            properties.put(maskValueAtKey, "[" + maskValueAtKey + "]");
-        }
-        return properties;
-    }
-
     private void update(final Properties properties, final String key, final String value) {
         if (properties != null && key != null) {
             if (value == null) {
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PStmtKeyCPDS.java b/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PStmtKeyCPDS.java
index 0bce400..083f3ba 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PStmtKeyCPDS.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PStmtKeyCPDS.java
@@ -95,7 +95,7 @@ public class PStmtKeyCPDS extends PStmtKey {
      *            An array of column indexes indicating the columns that should be returned from the inserted row or
      *            rows.
      */
-    public PStmtKeyCPDS(final String sql, final int columnIndexes[]) {
+    public PStmtKeyCPDS(final String sql, final int[] columnIndexes) {
         super(sql, null, columnIndexes);
     }
 
@@ -107,7 +107,7 @@ public class PStmtKeyCPDS extends PStmtKey {
      * @param columnNames
      *            An array of column names indicating the columns that should be returned from the inserted row or rows.
      */
-    public PStmtKeyCPDS(final String sql, final String columnNames[]) {
+    public PStmtKeyCPDS(final String sql, final String[] columnNames) {
         super(sql, null, columnNames);
     }
 }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PooledConnectionImpl.java b/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PooledConnectionImpl.java
index 147ee26..c2cf544 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PooledConnectionImpl.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PooledConnectionImpl.java
@@ -35,6 +35,7 @@ import org.apache.tomcat.dbcp.dbcp2.PStmtKey;
 import org.apache.tomcat.dbcp.dbcp2.PoolableCallableStatement;
 import org.apache.tomcat.dbcp.dbcp2.PoolablePreparedStatement;
 import org.apache.tomcat.dbcp.dbcp2.PoolingConnection.StatementType;
+import org.apache.tomcat.dbcp.pool2.DestroyMode;
 import org.apache.tomcat.dbcp.pool2.KeyedObjectPool;
 import org.apache.tomcat.dbcp.pool2.KeyedPooledObjectFactory;
 import org.apache.tomcat.dbcp.pool2.PooledObject;
@@ -108,10 +109,7 @@ class PooledConnectionImpl
     /**
      * My {@link KeyedPooledObjectFactory} method for activating {@link PreparedStatement}s.
      *
-     * @param key
-     *            Ignored.
-     * @param pooledObject
-     *            Ignored.
+     * @param pooledObject Activates the underlying object.
      */
     @Override
     public void activateObject(final PStmtKey key, final PooledObject<DelegatingPreparedStatement> pooledObject)
@@ -214,7 +212,7 @@ class PooledConnectionImpl
      *            rows.
      * @return a key to uniquely identify a prepared statement.
      */
-    protected PStmtKey createKey(final String sql, final int columnIndexes[]) {
+    protected PStmtKey createKey(final String sql, final int[] columnIndexes) {
         return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), getSchemaOrNull(), columnIndexes);
     }
 
@@ -327,7 +325,7 @@ class PooledConnectionImpl
      *            An array of column names indicating the columns that should be returned from the inserted row or rows.
      * @return a key to uniquely identify a prepared statement.
      */
-    protected PStmtKey createKey(final String sql, final String columnNames[]) {
+    protected PStmtKey createKey(final String sql, final String[] columnNames) {
         return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(), getSchemaOrNull(), columnNames);
     }
 
@@ -345,6 +343,12 @@ class PooledConnectionImpl
         pooledObject.getObject().getInnermostDelegate().close();
     }
 
+    @Override
+    public void destroyObject(PStmtKey key, PooledObject<DelegatingPreparedStatement> p,
+            DestroyMode mode) throws Exception {
+        destroyObject(key, p);
+    }
+
     /**
      * Closes the physical connection and checks that the logical connection was closed as well.
      */
@@ -572,9 +576,10 @@ class PooledConnectionImpl
     /**
      * Creates or obtains a {@link PreparedStatement} from my pool.
      *
-     * @param sql
-     *            the SQL statement.
+     * @param sql the SQL statement.
      * @return a {@link PoolablePreparedStatement}
+     * @throws SQLException Thrown if a database access error occurs, this method is called on a closed connection, or
+     *         the borrow failed.
      */
     PreparedStatement prepareStatement(final String sql) throws SQLException {
         if (pStmtPool == null) {
@@ -598,6 +603,8 @@ class PooledConnectionImpl
      *            a flag indicating whether auto-generated keys should be returned; one of
      *            <code>Statement.RETURN_GENERATED_KEYS</code> or <code>Statement.NO_GENERATED_KEYS</code>.
      * @return a {@link PoolablePreparedStatement}
+     * @throws SQLException Thrown if a database access error occurs, this method is called on a closed connection, or
+     *         the borrow failed.
      * @see Connection#prepareStatement(String, int)
      */
     PreparedStatement prepareStatement(final String sql, final int autoGeneratedKeys) throws SQLException {
@@ -613,7 +620,7 @@ class PooledConnectionImpl
         }
     }
 
-    PreparedStatement prepareStatement(final String sql, final int columnIndexes[]) throws SQLException {
+    PreparedStatement prepareStatement(final String sql, final int[] columnIndexes) throws SQLException {
         if (pStmtPool == null) {
             return connection.prepareStatement(sql, columnIndexes);
         }
@@ -640,6 +647,8 @@ class PooledConnectionImpl
      *            <code>ResultSet.CONCUR_UPDATABLE</code>.
      *
      * @return a {@link PoolablePreparedStatement}.
+     * @throws SQLException Thrown if a database access error occurs, this method is called on a closed connection, or
+     *         the borrow failed.
      * @see Connection#prepareStatement(String, int, int)
      */
     PreparedStatement prepareStatement(final String sql, final int resultSetType, final int resultSetConcurrency)
@@ -670,7 +679,7 @@ class PooledConnectionImpl
         }
     }
 
-    PreparedStatement prepareStatement(final String sql, final String columnNames[]) throws SQLException {
+    PreparedStatement prepareStatement(final String sql, final String[] columnNames) throws SQLException {
         if (pStmtPool == null) {
             return connection.prepareStatement(sql, columnNames);
         }
@@ -726,4 +735,30 @@ class PooledConnectionImpl
     public boolean validateObject(final PStmtKey key, final PooledObject<DelegatingPreparedStatement> pooledObject) {
         return true;
     }
+
+    /**
+     * @since 2.6.0
+     */
+    @Override
+    public synchronized String toString() {
+        final StringBuilder builder = new StringBuilder(super.toString());
+        builder.append("[connection=");
+        builder.append(connection);
+        builder.append(", delegatingConnection=");
+        builder.append(delegatingConnection);
+        builder.append(", logicalConnection=");
+        builder.append(logicalConnection);
+        builder.append(", eventListeners=");
+        builder.append(eventListeners);
+        builder.append(", statementEventListeners=");
+        builder.append(statementEventListeners);
+        builder.append(", closed=");
+        builder.append(closed);
+        builder.append(", pStmtPool=");
+        builder.append(pStmtPool);
+        builder.append(", accessToUnderlyingConnectionAllowed=");
+        builder.append(accessToUnderlyingConnectionAllowed);
+        builder.append("]");
+        return builder.toString();
+    }
 }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/datasources/CPDSConnectionFactory.java b/java/org/apache/tomcat/dbcp/dbcp2/datasources/CPDSConnectionFactory.java
index 93363a4..6c91099 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/datasources/CPDSConnectionFactory.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/datasources/CPDSConnectionFactory.java
@@ -31,6 +31,7 @@ import javax.sql.ConnectionPoolDataSource;
 import javax.sql.PooledConnection;
 
 import org.apache.tomcat.dbcp.dbcp2.Utils;
+import org.apache.tomcat.dbcp.pool2.DestroyMode;
 import org.apache.tomcat.dbcp.pool2.ObjectPool;
 import org.apache.tomcat.dbcp.pool2.PooledObject;
 import org.apache.tomcat.dbcp.pool2.PooledObjectFactory;
@@ -58,8 +59,7 @@ class CPDSConnectionFactory
     /**
      * Map of PooledConnections for which close events are ignored. Connections are muted when they are being validated.
      */
-    private final Set<PooledConnection> validatingSet = Collections
-            .newSetFromMap(new ConcurrentHashMap<PooledConnection, Boolean>());
+    private final Set<PooledConnection> validatingSet = Collections.newSetFromMap(new ConcurrentHashMap<PooledConnection,Boolean>());
 
     /**
      * Map of PooledConnectionAndInfo instances
@@ -150,7 +150,7 @@ class CPDSConnectionFactory
 
     @Override
     public synchronized PooledObject<PooledConnectionAndInfo> makeObject() {
-        PooledConnectionAndInfo pci;
+        final PooledConnectionAndInfo pci;
         try {
             PooledConnection pc = null;
             if (userName == null) {
@@ -182,6 +182,13 @@ class CPDSConnectionFactory
         doDestroyObject(p.getObject());
     }
 
+
+    @Override
+    public void destroyObject(PooledObject<PooledConnectionAndInfo> p, DestroyMode mode)
+            throws Exception {
+        destroyObject(p);
+    }
+
     private void doDestroyObject(final PooledConnectionAndInfo pci) throws Exception {
         final PooledConnection pc = pci.getPooledConnection();
         pc.removeConnectionEventListener(this);
@@ -226,11 +233,7 @@ class CPDSConnectionFactory
                 conn = pconn.getConnection();
                 stmt = conn.createStatement();
                 rset = stmt.executeQuery(validationQuery);
-                if (rset.next()) {
-                    valid = true;
-                } else {
-                    valid = false;
-                }
+                valid = rset.next();
                 if (rollbackAfterValidation) {
                     conn.rollback();
                 }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSource.java b/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSource.java
index e9457e6..a556f56 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSource.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSource.java
@@ -24,7 +24,6 @@ import java.nio.charset.StandardCharsets;
 import java.sql.Connection;
 import java.sql.SQLException;
 import java.sql.SQLFeatureNotSupportedException;
-import java.util.NoSuchElementException;
 import java.util.Properties;
 import java.util.logging.Logger;
 
@@ -913,9 +912,6 @@ public abstract class InstanceKeyDataSource implements DataSource, Referenceable
         PooledConnectionAndInfo info = null;
         try {
             info = getPooledConnectionAndInfo(userName, userPassword);
-        } catch (final NoSuchElementException e) {
-            closeDueToException(info);
-            throw new SQLException("Cannot borrow connection from pool", e);
         } catch (final RuntimeException | SQLException e) {
             closeDueToException(info);
             throw e;
@@ -950,9 +946,6 @@ public abstract class InstanceKeyDataSource implements DataSource, Referenceable
             for (int i = 0; i < 10; i++) { // Bound the number of retries - only needed if bad instances return
                 try {
                     info = getPooledConnectionAndInfo(userName, userPassword);
-                } catch (final NoSuchElementException e) {
-                    closeDueToException(info);
-                    throw new SQLException("Cannot borrow connection from pool", e);
                 } catch (final RuntimeException | SQLException e) {
                     closeDueToException(info);
                     throw e;
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSourceFactory.java b/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSourceFactory.java
index 0e2c1eb..defa46a 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSourceFactory.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSourceFactory.java
@@ -46,7 +46,7 @@ abstract class InstanceKeyDataSourceFactory implements ObjectFactory {
 
     static synchronized String registerNewInstance(final InstanceKeyDataSource ds) {
         int max = 0;
-        for (String s : instanceMap.keySet()) {
+        for (final String s : instanceMap.keySet()) {
             if (s != null) {
                 try {
                     max = Math.max(max, Integer.parseInt(s));
@@ -81,7 +81,7 @@ abstract class InstanceKeyDataSourceFactory implements ObjectFactory {
     public static void closeAll() throws Exception {
         // Get iterator to loop over all instances of this data source.
         final List<Throwable> exceptionList = new ArrayList<>(instanceMap.size());
-        for (Entry<String, InstanceKeyDataSource> next : instanceMap.entrySet()) {
+        for (final Entry<String, InstanceKeyDataSource> next : instanceMap.entrySet()) {
             // Bullet-proof to avoid anything else but problems from InstanceKeyDataSource#close().
             if (next != null) {
                 final InstanceKeyDataSource value = next.getValue();
@@ -166,7 +166,7 @@ abstract class InstanceKeyDataSourceFactory implements ObjectFactory {
         // Pool properties
         refAddr = ref.get("blockWhenExhausted");
         if (refAddr != null && refAddr.getContent() != null) {
-            ikds.setDefaultBlockWhenExhausted(Boolean.valueOf(refAddr.getContent().toString()).booleanValue());
+            ikds.setDefaultBlockWhenExhausted(Boolean.parseBoolean(refAddr.getContent().toString()));
         }
 
         refAddr = ref.get("evictionPolicyClassName");
@@ -177,7 +177,7 @@ abstract class InstanceKeyDataSourceFactory implements ObjectFactory {
         // Pool properties
         refAddr = ref.get("lifo");
         if (refAddr != null && refAddr.getContent() != null) {
-            ikds.setDefaultLifo(Boolean.valueOf(refAddr.getContent().toString()).booleanValue());
+            ikds.setDefaultLifo(Boolean.parseBoolean(refAddr.getContent().toString()));
         }
 
         refAddr = ref.get("maxIdlePerKey");
@@ -217,22 +217,22 @@ abstract class InstanceKeyDataSourceFactory implements ObjectFactory {
 
         refAddr = ref.get("testOnCreate");
         if (refAddr != null && refAddr.getContent() != null) {
-            ikds.setDefaultTestOnCreate(Boolean.valueOf(refAddr.getContent().toString()).booleanValue());
+            ikds.setDefaultTestOnCreate(Boolean.parseBoolean(refAddr.getContent().toString()));
         }
 
         refAddr = ref.get("testOnBorrow");
         if (refAddr != null && refAddr.getContent() != null) {
-            ikds.setDefaultTestOnBorrow(Boolean.valueOf(refAddr.getContent().toString()).booleanValue());
+            ikds.setDefaultTestOnBorrow(Boolean.parseBoolean(refAddr.getContent().toString()));
         }
 
         refAddr = ref.get("testOnReturn");
         if (refAddr != null && refAddr.getContent() != null) {
-            ikds.setDefaultTestOnReturn(Boolean.valueOf(refAddr.getContent().toString()).booleanValue());
+            ikds.setDefaultTestOnReturn(Boolean.parseBoolean(refAddr.getContent().toString()));
         }
 
         refAddr = ref.get("testWhileIdle");
         if (refAddr != null && refAddr.getContent() != null) {
-            ikds.setDefaultTestWhileIdle(Boolean.valueOf(refAddr.getContent().toString()).booleanValue());
+            ikds.setDefaultTestWhileIdle(Boolean.parseBoolean(refAddr.getContent().toString()));
         }
 
         refAddr = ref.get("timeBetweenEvictionRunsMillis");
@@ -254,7 +254,7 @@ abstract class InstanceKeyDataSourceFactory implements ObjectFactory {
 
         refAddr = ref.get("rollbackAfterValidation");
         if (refAddr != null && refAddr.getContent() != null) {
-            ikds.setRollbackAfterValidation(Boolean.valueOf(refAddr.getContent().toString()).booleanValue());
+            ikds.setRollbackAfterValidation(Boolean.parseBoolean(refAddr.getContent().toString()));
         }
 
         refAddr = ref.get("maxConnLifetimeMillis");
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/datasources/KeyedCPDSConnectionFactory.java b/java/org/apache/tomcat/dbcp/dbcp2/datasources/KeyedCPDSConnectionFactory.java
index 3f15b79..ada37fe 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/datasources/KeyedCPDSConnectionFactory.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/datasources/KeyedCPDSConnectionFactory.java
@@ -32,6 +32,7 @@ import javax.sql.ConnectionPoolDataSource;
 import javax.sql.PooledConnection;
 
 import org.apache.tomcat.dbcp.dbcp2.Utils;
+import org.apache.tomcat.dbcp.pool2.DestroyMode;
 import org.apache.tomcat.dbcp.pool2.KeyedObjectPool;
 import org.apache.tomcat.dbcp.pool2.KeyedPooledObjectFactory;
 import org.apache.tomcat.dbcp.pool2.PooledObject;
@@ -59,8 +60,7 @@ class KeyedCPDSConnectionFactory implements KeyedPooledObjectFactory<UserPassKey
     /**
      * Map of PooledConnections for which close events are ignored. Connections are muted when they are being validated.
      */
-    private final Set<PooledConnection> validatingSet = Collections
-            .newSetFromMap(new ConcurrentHashMap<PooledConnection, Boolean>());
+    private final Set<PooledConnection> validatingSet = Collections.newSetFromMap(new ConcurrentHashMap<PooledConnection,Boolean>());
 
     /**
      * Map of PooledConnectionAndInfo instances
@@ -113,8 +113,6 @@ class KeyedCPDSConnectionFactory implements KeyedPooledObjectFactory<UserPassKey
      */
     @Override
     public synchronized PooledObject<PooledConnectionAndInfo> makeObject(final UserPassKey upkey) throws Exception {
-        PooledConnectionAndInfo pci = null;
-
         PooledConnection pc = null;
         final String userName = upkey.getUsername();
         final String password = upkey.getPassword();
@@ -131,7 +129,7 @@ class KeyedCPDSConnectionFactory implements KeyedPooledObjectFactory<UserPassKey
         // should we add this object as a listener or the pool.
         // consider the validateObject method in decision
         pc.addConnectionEventListener(this);
-        pci = new PooledConnectionAndInfo(pc, userName, upkey.getPasswordCharArray());
+        final PooledConnectionAndInfo pci = new PooledConnectionAndInfo(pc, userName, upkey.getPasswordCharArray());
         pcMap.put(pc, pci);
 
         return new DefaultPooledObject<>(pci);
@@ -148,6 +146,12 @@ class KeyedCPDSConnectionFactory implements KeyedPooledObjectFactory<UserPassKey
         pc.close();
     }
 
+    @Override
+    public void destroyObject(UserPassKey key, PooledObject<PooledConnectionAndInfo> p,
+            DestroyMode mode) throws Exception {
+        destroyObject(key, p);
+    }
+
     /**
      * Validates a pooled connection.
      *
@@ -194,11 +198,7 @@ class KeyedCPDSConnectionFactory implements KeyedPooledObjectFactory<UserPassKey
                 conn = pconn.getConnection();
                 stmt = conn.createStatement();
                 rset = stmt.executeQuery(validationQuery);
-                if (rset.next()) {
-                    valid = true;
-                } else {
-                    valid = false;
-                }
+                valid = rset.next();
                 if (rollbackAfterValidation) {
                     conn.rollback();
                 }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/datasources/PoolKey.java b/java/org/apache/tomcat/dbcp/dbcp2/datasources/PoolKey.java
index f38e04f..17f8551 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/datasources/PoolKey.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/datasources/PoolKey.java
@@ -18,6 +18,7 @@
 package org.apache.tomcat.dbcp.dbcp2.datasources;
 
 import java.io.Serializable;
+import java.util.Objects;
 
 /**
  * @since 2.0
@@ -45,37 +46,22 @@ class PoolKey implements Serializable {
             return false;
         }
         final PoolKey other = (PoolKey) obj;
-        if (dataSourceName == null) {
-            if (other.dataSourceName != null) {
-                return false;
-            }
-        } else if (!dataSourceName.equals(other.dataSourceName)) {
+        if (!Objects.equals(dataSourceName, other.dataSourceName)) {
             return false;
         }
-        if (userName == null) {
-            if (other.userName != null) {
-                return false;
-            }
-        } else if (!userName.equals(other.userName)) {
-            return false;
-        }
-        return true;
+        return Objects.equals(userName, other.userName);
     }
 
     @Override
     public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((dataSourceName == null) ? 0 : dataSourceName.hashCode());
-        result = prime * result + ((userName == null) ? 0 : userName.hashCode());
-        return result;
+        return Objects.hash(dataSourceName, userName);
     }
 
     @Override
     public String toString() {
-        final StringBuffer sb = new StringBuffer(50);
+        final StringBuilder sb = new StringBuilder(50);
         sb.append("PoolKey(");
-        sb.append(userName).append(", ").append(dataSourceName);
+        sb.append("UserName").append(", ").append(dataSourceName);
         sb.append(')');
         return sb.toString();
     }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/datasources/UserPassKey.java b/java/org/apache/tomcat/dbcp/dbcp2/datasources/UserPassKey.java
index e357028..b589809 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/datasources/UserPassKey.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/datasources/UserPassKey.java
@@ -18,6 +18,7 @@
 package org.apache.tomcat.dbcp.dbcp2.datasources;
 
 import java.io.Serializable;
+import java.util.Objects;
 
 import org.apache.tomcat.dbcp.dbcp2.Utils;
 
@@ -75,14 +76,7 @@ class UserPassKey implements Serializable {
             return false;
         }
         final UserPassKey other = (UserPassKey) obj;
-        if (userName == null) {
-            if (other.userName != null) {
-                return false;
-            }
-        } else if (!userName.equals(other.userName)) {
-            return false;
-        }
-        return true;
+        return Objects.equals(userName, other.userName);
     }
 
     /**
@@ -117,18 +111,7 @@ class UserPassKey implements Serializable {
      */
     @Override
     public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((userName == null) ? 0 : userName.hashCode());
-        return result;
+        return Objects.hash(userName);
     }
 
-    @Override
-    public String toString() {
-        final StringBuffer sb = new StringBuffer(super.toString());
-        sb.append("[");
-        sb.append(userName);
-        sb.append(']');
-        return sb.toString();
-    }
 }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/datasources/package-info.java b/java/org/apache/tomcat/dbcp/dbcp2/datasources/package-info.java
index 531db68..5b24360 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/datasources/package-info.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/datasources/package-info.java
@@ -82,7 +82,7 @@
  * <strong>java:comp/env</strong> namespace.  So the JNDI path given for
  * the dataSourceName parameter is valid for a
  * <code>ConnectionPoolDataSource</code> that is deployed as given in the
- * <a href="../cpdsadapter/package.html">cpdsadapter example</a>
+ * <a href="../cpdsadapter/package-summary.html">cpdsadapter example</a>
  * </p>
  *
  * <p>
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 7a0979f..185c386 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -215,6 +215,10 @@
         Update the internal fork of Apache Commons Pool to 2.9.1-SNAPSHOT
         (2021-01-15). (markt)
       </add>
+      <add>
+        Update the internal fork of Apache Commons DBCP to 2.9.0-SNAPSHOT
+        (2021-01-15). (markt)
+      </add>
     </changelog>
   </subsection>
 </section>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


[tomcat] 02/02: Fix back-port of Pool2 update not to use default methods

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 5601e5183ecd32fb53c02e31e58416c263bb172a
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri Jan 15 16:39:00 2021 +0000

    Fix back-port of Pool2 update not to use default methods
---
 java/org/apache/tomcat/dbcp/pool2/KeyedObjectPool.java         |  4 +---
 .../org/apache/tomcat/dbcp/pool2/KeyedPooledObjectFactory.java |  4 +---
 java/org/apache/tomcat/dbcp/pool2/ObjectPool.java              |  4 +---
 java/org/apache/tomcat/dbcp/pool2/PoolUtils.java               | 10 ++++++++++
 java/org/apache/tomcat/dbcp/pool2/PooledObjectFactory.java     |  4 +---
 .../apache/tomcat/dbcp/pool2/impl/SoftReferenceObjectPool.java |  6 ++++++
 6 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/java/org/apache/tomcat/dbcp/pool2/KeyedObjectPool.java b/java/org/apache/tomcat/dbcp/pool2/KeyedObjectPool.java
index 0228dff..72e7b15 100644
--- a/java/org/apache/tomcat/dbcp/pool2/KeyedObjectPool.java
+++ b/java/org/apache/tomcat/dbcp/pool2/KeyedObjectPool.java
@@ -278,9 +278,7 @@ public interface KeyedObjectPool<K, V> extends Closeable {
      * @throws Exception if the instance cannot be invalidated
      * @since 2.9.0
      */
-    default void invalidateObject(final K key, final V obj, final DestroyMode mode) throws Exception {
-        invalidateObject(key, obj);
-    }
+    void invalidateObject(final K key, final V obj, final DestroyMode mode) throws Exception;
 
     /**
      * Return an instance to the pool. By contract, {@code obj}
diff --git a/java/org/apache/tomcat/dbcp/pool2/KeyedPooledObjectFactory.java b/java/org/apache/tomcat/dbcp/pool2/KeyedPooledObjectFactory.java
index 0a24a47..e1a9d74 100644
--- a/java/org/apache/tomcat/dbcp/pool2/KeyedPooledObjectFactory.java
+++ b/java/org/apache/tomcat/dbcp/pool2/KeyedPooledObjectFactory.java
@@ -129,9 +129,7 @@ public interface KeyedPooledObjectFactory<K, V> {
      * @see DestroyMode
      * @since 2.9.0
      */
-    default void destroyObject(final K key, final PooledObject<V> p, final DestroyMode mode) throws Exception {
-        destroyObject(key, p);
-    }
+    void destroyObject(final K key, final PooledObject<V> p, final DestroyMode mode) throws Exception;
 
     /**
      * Ensures that the instance is safe to be returned by the pool.
diff --git a/java/org/apache/tomcat/dbcp/pool2/ObjectPool.java b/java/org/apache/tomcat/dbcp/pool2/ObjectPool.java
index 7e14caa..2647687 100644
--- a/java/org/apache/tomcat/dbcp/pool2/ObjectPool.java
+++ b/java/org/apache/tomcat/dbcp/pool2/ObjectPool.java
@@ -199,9 +199,7 @@ public interface ObjectPool<T> extends Closeable {
      * @throws Exception if the instance cannot be invalidated
      * @since 2.9.0
      */
-    default void invalidateObject(final T obj, final DestroyMode mode) throws Exception {
-        invalidateObject(obj);
-    }
+    void invalidateObject(final T obj, final DestroyMode mode) throws Exception;
 
     /**
      * Returns an instance to the pool. By contract, {@code obj}
diff --git a/java/org/apache/tomcat/dbcp/pool2/PoolUtils.java b/java/org/apache/tomcat/dbcp/pool2/PoolUtils.java
index a187c31..b087507 100644
--- a/java/org/apache/tomcat/dbcp/pool2/PoolUtils.java
+++ b/java/org/apache/tomcat/dbcp/pool2/PoolUtils.java
@@ -538,6 +538,11 @@ public final class PoolUtils {
             }
         }
 
+        @Override
+        public void destroyObject(PooledObject<T> p, DestroyMode mode) throws Exception {
+            destroyObject(p);
+        }
+
         /**
          * {@inheritDoc}
          */
@@ -657,6 +662,11 @@ public final class PoolUtils {
             }
         }
 
+        @Override
+        public void destroyObject(K key, PooledObject<V> p, DestroyMode mode) throws Exception {
+            destroyObject(key, p);
+        }
+
         /**
          * {@inheritDoc}
          */
diff --git a/java/org/apache/tomcat/dbcp/pool2/PooledObjectFactory.java b/java/org/apache/tomcat/dbcp/pool2/PooledObjectFactory.java
index 9c95d0d..daff431 100644
--- a/java/org/apache/tomcat/dbcp/pool2/PooledObjectFactory.java
+++ b/java/org/apache/tomcat/dbcp/pool2/PooledObjectFactory.java
@@ -122,9 +122,7 @@ public interface PooledObjectFactory<T> {
    * @see DestroyMode
    * @since 2.9.0
    */
-  default void destroyObject(final PooledObject<T> p, final DestroyMode mode) throws Exception {
-      destroyObject(p);
-  }
+  void destroyObject(final PooledObject<T> p, final DestroyMode mode) throws Exception;
 
   /**
    * Ensures that the instance is safe to be returned by the pool.
diff --git a/java/org/apache/tomcat/dbcp/pool2/impl/SoftReferenceObjectPool.java b/java/org/apache/tomcat/dbcp/pool2/impl/SoftReferenceObjectPool.java
index f9cce30..6d653e3 100644
--- a/java/org/apache/tomcat/dbcp/pool2/impl/SoftReferenceObjectPool.java
+++ b/java/org/apache/tomcat/dbcp/pool2/impl/SoftReferenceObjectPool.java
@@ -24,6 +24,7 @@ import java.util.Iterator;
 import java.util.NoSuchElementException;
 
 import org.apache.tomcat.dbcp.pool2.BaseObjectPool;
+import org.apache.tomcat.dbcp.pool2.DestroyMode;
 import org.apache.tomcat.dbcp.pool2.PoolUtils;
 import org.apache.tomcat.dbcp.pool2.PooledObjectFactory;
 
@@ -245,6 +246,11 @@ public class SoftReferenceObjectPool<T> extends BaseObjectPool<T> {
         notifyAll(); // numActive has changed
     }
 
+    @Override
+    public void invalidateObject(T obj, DestroyMode mode) throws Exception {
+        invalidateObject(obj);
+    }
+
     /**
      * Creates an object, and places it into the pool. addObject() is useful for
      * "pre-loading" a pool with idle objects.


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org