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/09/02 16:39:04 UTC

[tomcat] branch 8.5.x updated: Update internal DBCP fork to 2021-06-05

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


The following commit(s) were added to refs/heads/8.5.x by this push:
     new 0cf7efb  Update internal DBCP fork to 2021-06-05
0cf7efb is described below

commit 0cf7efb75616c71acc7477723db0f3db7c8c4cb1
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Thu Sep 2 17:15:27 2021 +0100

    Update internal DBCP fork to 2021-06-05
---
 MERGE.txt                                          |   6 +-
 .../apache/tomcat/dbcp/dbcp2/AbandonedTrace.java   |   7 +-
 .../apache/tomcat/dbcp/dbcp2/BasicDataSource.java  |  69 +++--
 .../tomcat/dbcp/dbcp2/BasicDataSourceMXBean.java   | 322 +--------------------
 .../dbcp/dbcp2/ConnectionFactoryFactory.java       |   2 +-
 java/org/apache/tomcat/dbcp/dbcp2/Constants.java   |  16 +-
 .../dbcp/dbcp2/DataSourceConnectionFactory.java    |   2 +-
 ...DataSourceMXBean.java => DataSourceMXBean.java} | 272 +++++++++--------
 .../tomcat/dbcp/dbcp2/DelegatingConnection.java    |  18 +-
 .../dbcp/dbcp2/DelegatingDatabaseMetaData.java     |  19 +-
 .../tomcat/dbcp/dbcp2/DelegatingResultSet.java     |  24 +-
 .../tomcat/dbcp/dbcp2/DelegatingStatement.java     |  19 +-
 java/org/apache/tomcat/dbcp/dbcp2/PStmtKey.java    |   4 +-
 .../tomcat/dbcp/dbcp2/PoolableConnection.java      |   6 +-
 .../dbcp/dbcp2/PoolableConnectionFactory.java      |   6 +-
 .../dbcp/dbcp2/PoolablePreparedStatement.java      |   2 +-
 .../tomcat/dbcp/dbcp2/PoolingConnection.java       |   2 +-
 .../tomcat/dbcp/dbcp2/PoolingDataSource.java       |  12 +-
 .../apache/tomcat/dbcp/dbcp2/PoolingDriver.java    |  21 +-
 java/org/apache/tomcat/dbcp/dbcp2/Utils.java       |   8 +-
 .../dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java  |  71 +++--
 .../dbcp2/cpdsadapter/PooledConnectionImpl.java    |  12 +-
 .../dbcp2/datasources/CPDSConnectionFactory.java   |   6 +-
 .../dbcp2/datasources/InstanceKeyDataSource.java   |  79 +++--
 .../datasources/InstanceKeyDataSourceFactory.java  |  20 +-
 .../datasources/KeyedCPDSConnectionFactory.java    |  30 +-
 .../dbcp2/datasources/PerUserPoolDataSource.java   |   2 +-
 .../dbcp2/datasources/PooledConnectionAndInfo.java |  11 +-
 .../dbcp2/datasources/SharedPoolDataSource.java    |   8 +-
 .../tomcat/dbcp/dbcp2/datasources/UserPassKey.java |  15 +-
 webapps/docs/changelog.xml                         |   4 +
 31 files changed, 408 insertions(+), 687 deletions(-)

diff --git a/MERGE.txt b/MERGE.txt
index ca9839a..4d7b5de 100644
--- a/MERGE.txt
+++ b/MERGE.txt
@@ -73,4 +73,8 @@ 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:
-e24196a95bbbc531eb3c5f1b19e1dc42fd78a783 (2021-01-15)
+1a0e9e8a61b7e8327a159516907778cd74da7a3b (2021-06-05)
+Note: Commits after this point started to make extensive use of the java.time.*
+      package which is not available in Java 7. It is anticipated that further
+      changes to the DBCP 2 fork in Tomcat 8.5.x will be limited to on-demand
+      back-port of bug fixes.
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/AbandonedTrace.java b/java/org/apache/tomcat/dbcp/dbcp2/AbandonedTrace.java
index 671e3e6..7ba6656 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/AbandonedTrace.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/AbandonedTrace.java
@@ -25,7 +25,7 @@ import java.util.List;
 import org.apache.tomcat.dbcp.pool2.TrackedUse;
 
 /**
- * Tracks db connection usage for recovering and reporting abandoned db connections.
+ * Tracks connection usage for recovering and reporting abandoned connections.
  * <p>
  * The JDBC Connection, Statement, and ResultSet classes extend this class.
  * </p>
@@ -38,7 +38,7 @@ public class AbandonedTrace implements TrackedUse {
     private final List<WeakReference<AbandonedTrace>> traceList = new ArrayList<>();
 
     /** Last time this connection was used. */
-    private volatile long lastUsedMillis = 0;
+    private volatile long lastUsedMillis;
 
     /**
      * Creates a new AbandonedTrace without config and without doing abandoned tracing.
@@ -153,7 +153,8 @@ public class AbandonedTrace implements TrackedUse {
                 if (trace != null && trace.equals(traceInList)) {
                     iter.remove();
                     break;
-                } else if (traceInList == null) {
+                }
+                if (traceInList == null) {
                     // Clean-up since we are here anyway
                     iter.remove();
                 }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.java b/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.java
index 8f11d75..67c6840 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.java
@@ -40,7 +40,9 @@ import java.util.logging.Logger;
 import javax.management.MBeanRegistration;
 import javax.management.MBeanServer;
 import javax.management.MalformedObjectNameException;
+import javax.management.NotCompliantMBeanException;
 import javax.management.ObjectName;
+import javax.management.StandardMBean;
 import javax.sql.DataSource;
 
 import org.apache.juli.logging.Log;
@@ -53,10 +55,11 @@ import org.apache.tomcat.dbcp.pool2.impl.GenericObjectPool;
 import org.apache.tomcat.dbcp.pool2.impl.GenericObjectPoolConfig;
 
 /**
+ * Basic implementation of <code>javax.sql.DataSource</code> that is configured via JavaBeans properties.
+ *
  * <p>
- * Basic implementation of <code>javax.sql.DataSource</code> that is configured via JavaBeans properties. This is not
- * the only way to combine the <em>commons-dbcp2</em> and <em>commons-pool2</em> packages, but provides a "one stop
- * shopping" solution for basic requirements.
+ * This is not the only way to combine the <em>commons-dbcp2</em> and <em>commons-pool2</em> packages, but provides a
+ * one-stop solution for basic requirements.
  * </p>
  *
  * @since 2.0
@@ -205,7 +208,7 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
     /**
      * The initial number of connections that are created when the pool is started.
      */
-    private int initialSize = 0;
+    private int initialSize;
 
     /**
      * The maximum number of milliseconds that the pool will wait (when there are no available connections) for a
@@ -217,9 +220,9 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
      * Prepared statement pooling for this pool. When this property is set to <code>true</code> both PreparedStatements
      * and CallableStatements are pooled.
      */
-    private boolean poolPreparedStatements = false;
+    private boolean poolPreparedStatements;
 
-    private boolean clearStatementPoolOnReturn = false;
+    private boolean clearStatementPoolOnReturn;
 
     /**
      * <p>
@@ -240,7 +243,7 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
      * The indication of whether objects will be validated as soon as they have been created by the pool. If the object
      * fails to validate, the borrow operation that triggered the creation will fail.
      */
-    private boolean testOnCreate = false;
+    private boolean testOnCreate;
 
     /**
      * The indication of whether objects will be validated before being borrowed from the pool. If the object fails to
@@ -251,7 +254,7 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
     /**
      * The indication of whether objects will be validated before being returned to the pool.
      */
-    private boolean testOnReturn = false;
+    private boolean testOnReturn;
 
     /**
      * The number of milliseconds to sleep between runs of the idle object evictor thread. When non-positive, no idle
@@ -284,7 +287,7 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
      * The indication of whether objects will be validated by the idle object evictor (if any). If an object fails to
      * validate, it will be dropped from the pool.
      */
-    private boolean testWhileIdle = false;
+    private boolean testWhileIdle;
 
     /**
      * The connection password to be passed to our JDBC driver to establish a connection.
@@ -330,7 +333,7 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
     /**
      * Controls access to the underlying connection.
      */
-    private boolean accessToUnderlyingConnectionAllowed = false;
+    private boolean accessToUnderlyingConnectionAllowed;
 
     private long maxConnLifetimeMillis = -1;
 
@@ -1491,7 +1494,7 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
 
     @Override
     public boolean isWrapperFor(final Class<?> iface) throws SQLException {
-        return false;
+        return iface != null && iface.isInstance(this);
     }
 
     private void jmxRegister() {
@@ -1504,9 +1507,11 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
         if (requestedName == null) {
             return;
         }
+        registeredJmxObjectName = registerJmxObjectName(requestedName, null);
         try {
-            ObjectNameWrapper.wrap(requestedName).registerMBean(this);
-        } catch (final MalformedObjectNameException e) {
+            final StandardMBean standardMBean = new StandardMBean(this, DataSourceMXBean.class);
+            registeredJmxObjectName.registerMBean(standardMBean);
+        } catch (final NotCompliantMBeanException e) {
             log.warn("The requested JMX name [" + requestedName + "] was not valid and will be ignored.");
         }
     }
@@ -1548,17 +1553,7 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
 
     @Override
     public ObjectName preRegister(final MBeanServer server, final ObjectName objectName) {
-        final String requestedName = getJmxName();
-        if (requestedName != null) {
-            try {
-                registeredJmxObjectName = ObjectNameWrapper.wrap(requestedName);
-            } catch (final MalformedObjectNameException e) {
-                log.warn("The requested JMX name [" + requestedName + "] was not valid and will be ignored.");
-            }
-        }
-        if (registeredJmxObjectName == null) {
-            registeredJmxObjectName = ObjectNameWrapper.wrap(objectName);
-        }
+        registeredJmxObjectName = registerJmxObjectName(getJmxName(), objectName);
         return ObjectNameWrapper.unwrap(registeredJmxObjectName);
     }
 
@@ -1703,7 +1698,7 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
      * @param connectionInitSqls Collection of SQL statements to execute on connection creation
      */
     public void setConnectionInitSqls(final Collection<String> connectionInitSqls) {
-        if (connectionInitSqls != null && connectionInitSqls.size() > 0) {
+        if (connectionInitSqls != null && !connectionInitSqls.isEmpty()) {
             ArrayList<String> newVal = null;
             for (final String s : connectionInitSqls) {
                 if (!isEmpty(s)) {
@@ -1735,7 +1730,7 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
         final String[] entries = connectionProperties.split(";");
         final Properties properties = new Properties();
         for (final String entry : entries) {
-            if (entry.length() > 0) {
+            if (!entry.isEmpty()) {
                 final int index = entry.indexOf('=');
                 if (index > 0) {
                     final String name = entry.substring(0, index);
@@ -1865,7 +1860,7 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
      * @since 2.1
      */
     public void setDisconnectionSqlCodes(final Collection<String> disconnectionSqlCodes) {
-        if (disconnectionSqlCodes != null && disconnectionSqlCodes.size() > 0) {
+        if (disconnectionSqlCodes != null && !disconnectionSqlCodes.isEmpty()) {
             HashSet<String> newVal = null;
             for (final String s : disconnectionSqlCodes) {
                 if (!isEmpty(s)) {
@@ -2461,7 +2456,10 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
 
     @Override
     public <T> T unwrap(final Class<T> iface) throws SQLException {
-        throw new SQLException("BasicDataSource is not a wrapper.");
+        if (isWrapperFor(iface)) {
+            return iface.cast(this);
+        }
+        throw new SQLException(this + " is not a wrapper for " + iface);
     }
 
     private void updateJmxName(final GenericObjectPoolConfig<?> config) {
@@ -2474,4 +2472,19 @@ public class BasicDataSource implements DataSource, BasicDataSourceMXBean, MBean
         config.setJmxNamePrefix(Constants.JMX_CONNECTION_POOL_PREFIX);
     }
 
+    private ObjectNameWrapper registerJmxObjectName(final String requestedName, final ObjectName objectName) {
+        ObjectNameWrapper objectNameWrapper = null;
+        if (requestedName != null) {
+            try {
+                objectNameWrapper = ObjectNameWrapper.wrap(requestedName);
+            } catch (final MalformedObjectNameException e) {
+                log.warn("The requested JMX name '" + requestedName + "' was not valid and will be ignored.");
+            }
+        }
+        if (objectNameWrapper == null) {
+            objectNameWrapper = ObjectNameWrapper.wrap(objectName);
+        }
+        return objectNameWrapper;
+    }
+
 }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceMXBean.java b/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceMXBean.java
index 8cd178d..06798a3 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceMXBean.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceMXBean.java
@@ -16,329 +16,23 @@
  */
 package org.apache.tomcat.dbcp.dbcp2;
 
-import java.sql.SQLException;
-
 /**
- * Defines the methods that will be made available via JMX.
+ * Interface to keep API compatibility. Methods listed here are not made available to
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/management/agent.html">JMX</a>.
+ * <p>
+ * As of 2.9.0, this interface extends {@link DataSourceMXBean}.
+ * </p>
  *
  * @since 2.0
  */
-public interface BasicDataSourceMXBean {
-
-    /**
-     * See {@link BasicDataSource#getAbandonedUsageTracking()}
-     *
-     * @return {@link BasicDataSource#getAbandonedUsageTracking()}
-     */
-    boolean getAbandonedUsageTracking();
-
-    /**
-     * See {@link BasicDataSource#getDefaultAutoCommit()}
-     *
-     * @return {@link BasicDataSource#getDefaultAutoCommit()}
-     */
-    Boolean getDefaultAutoCommit();
-
-    /**
-     * See {@link BasicDataSource#getDefaultReadOnly()}
-     *
-     * @return {@link BasicDataSource#getDefaultReadOnly()}
-     */
-    Boolean getDefaultReadOnly();
-
-    /**
-     * See {@link BasicDataSource#getDefaultTransactionIsolation()}
-     *
-     * @return {@link BasicDataSource#getDefaultTransactionIsolation()}
-     */
-    int getDefaultTransactionIsolation();
-
-    /**
-     * See {@link BasicDataSource#getDefaultCatalog()}
-     *
-     * @return {@link BasicDataSource#getDefaultCatalog()}
-     */
-    String getDefaultCatalog();
-
-    /**
-     * See {@link BasicDataSource#getDefaultSchema()}
-     *
-     * @return {@link BasicDataSource#getDefaultSchema()}
-     * @since 2.5.0
-     */
-    String getDefaultSchema();
-
-    /**
-     * See {@link BasicDataSource#getCacheState()}
-     *
-     * @return {@link BasicDataSource#getCacheState()}
-     */
-    boolean getCacheState();
-
-    /**
-     * See {@link BasicDataSource#getDriverClassName()}
-     *
-     * @return {@link BasicDataSource#getDriverClassName()}
-     */
-    String getDriverClassName();
-
-    /**
-     * See {@link BasicDataSource#getLifo()}
-     *
-     * @return {@link BasicDataSource#getLifo()}
-     */
-    boolean getLifo();
-
-    /**
-     * See {@link BasicDataSource#getMaxTotal()}
-     *
-     * @return {@link BasicDataSource#getMaxTotal()}
-     */
-    int getMaxTotal();
-
-    /**
-     * See {@link BasicDataSource#getMaxIdle()}
-     *
-     * @return {@link BasicDataSource#getMaxIdle()}
-     */
-    int getMaxIdle();
-
-    /**
-     * See {@link BasicDataSource#getMinIdle()}
-     *
-     * @return {@link BasicDataSource#getMinIdle()}
-     */
-    int getMinIdle();
-
-    /**
-     * See {@link BasicDataSource#getInitialSize()}
-     *
-     * @return {@link BasicDataSource#getInitialSize()}
-     */
-    int getInitialSize();
-
-    /**
-     * See {@link BasicDataSource#getMaxWaitMillis()}
-     *
-     * @return {@link BasicDataSource#getMaxWaitMillis()}
-     */
-    long getMaxWaitMillis();
-
-    /**
-     * See {@link BasicDataSource#isPoolPreparedStatements()}
-     *
-     * @return {@link BasicDataSource#isPoolPreparedStatements()}
-     */
-    boolean isPoolPreparedStatements();
-
-    /**
-     * See {@link BasicDataSource#isClearStatementPoolOnReturn()}
-     *
-     * @return {@link BasicDataSource#isClearStatementPoolOnReturn()}
-     * @since 2.8.0
-     */
-    boolean isClearStatementPoolOnReturn();
-
-    /**
-     * See {@link BasicDataSource#getMaxOpenPreparedStatements()}
-     *
-     * @return {@link BasicDataSource#getMaxOpenPreparedStatements()}
-     */
-    int getMaxOpenPreparedStatements();
-
-    /**
-     * See {@link BasicDataSource#getTestOnCreate()}
-     *
-     * @return {@link BasicDataSource#getTestOnCreate()}
-     */
-    boolean getTestOnCreate();
-
-    /**
-     * See {@link BasicDataSource#getTestOnBorrow()}
-     *
-     * @return {@link BasicDataSource#getTestOnBorrow()}
-     */
-    boolean getTestOnBorrow();
-
-    /**
-     * See {@link BasicDataSource#getTimeBetweenEvictionRunsMillis()}
-     *
-     * @return {@link BasicDataSource#getTimeBetweenEvictionRunsMillis()}
-     */
-    long getTimeBetweenEvictionRunsMillis();
-
-    /**
-     * See {@link BasicDataSource#getNumTestsPerEvictionRun()}
-     *
-     * @return {@link BasicDataSource#getNumTestsPerEvictionRun()}
-     */
-    int getNumTestsPerEvictionRun();
-
-    /**
-     * See {@link BasicDataSource#getMinEvictableIdleTimeMillis()}
-     *
-     * @return {@link BasicDataSource#getMinEvictableIdleTimeMillis()}
-     */
-    long getMinEvictableIdleTimeMillis();
-
-    /**
-     * See {@link BasicDataSource#getSoftMinEvictableIdleTimeMillis()}
-     *
-     * @return {@link BasicDataSource#getSoftMinEvictableIdleTimeMillis()}
-     */
-    long getSoftMinEvictableIdleTimeMillis();
-
-    /**
-     * See {@link BasicDataSource#getTestWhileIdle()}
-     *
-     * @return {@link BasicDataSource#getTestWhileIdle()}
-     */
-    boolean getTestWhileIdle();
-
-    /**
-     * See {@link BasicDataSource#getNumActive()}
-     *
-     * @return {@link BasicDataSource#getNumActive()}
-     */
-    int getNumActive();
-
-    /**
-     * See {@link BasicDataSource#getNumIdle()}
-     *
-     * @return {@link BasicDataSource#getNumIdle()}
-     */
-    int getNumIdle();
+public interface BasicDataSourceMXBean extends DataSourceMXBean {
 
     /**
      * See {@link BasicDataSource#getPassword()}
      *
      * @return {@link BasicDataSource#getPassword()}
+     * @deprecated exposing password via JMX is an Information Exposure issue.
      */
+    @Deprecated
     String getPassword();
-
-    /**
-     * See {@link BasicDataSource#getUrl()}
-     *
-     * @return {@link BasicDataSource#getUrl()}
-     */
-    String getUrl();
-
-    /**
-     * See {@link BasicDataSource#getUsername()}
-     *
-     * @return {@link BasicDataSource#getUsername()}
-     */
-    String getUsername();
-
-    /**
-     * See {@link BasicDataSource#getValidationQuery()}
-     *
-     * @return {@link BasicDataSource#getValidationQuery()}
-     */
-    String getValidationQuery();
-
-    /**
-     * See {@link BasicDataSource#getValidationQueryTimeout()}
-     *
-     * @return {@link BasicDataSource#getValidationQueryTimeout()}
-     */
-    int getValidationQueryTimeout();
-
-    /**
-     * See {@link BasicDataSource#getConnectionInitSqlsAsArray()}
-     *
-     * @return {@link BasicDataSource#getConnectionInitSqlsAsArray()}
-     */
-    String[] getConnectionInitSqlsAsArray();
-
-    /**
-     * See {@link BasicDataSource#isAccessToUnderlyingConnectionAllowed()}
-     *
-     * @return {@link BasicDataSource#isAccessToUnderlyingConnectionAllowed()}
-     */
-    boolean isAccessToUnderlyingConnectionAllowed();
-
-    /**
-     * See {@link BasicDataSource#getMaxConnLifetimeMillis()}
-     *
-     * @return {@link BasicDataSource#getMaxConnLifetimeMillis()}
-     */
-    long getMaxConnLifetimeMillis();
-
-    /**
-     * See {@link BasicDataSource#getLogExpiredConnections()}
-     *
-     * @return {@link BasicDataSource#getLogExpiredConnections()}
-     * @since 2.1
-     */
-    boolean getLogExpiredConnections();
-
-    /**
-     * See {@link BasicDataSource#getRemoveAbandonedOnBorrow()}
-     *
-     * @return {@link BasicDataSource#getRemoveAbandonedOnBorrow()}
-     */
-    boolean getRemoveAbandonedOnBorrow();
-
-    /**
-     * See {@link BasicDataSource#getRemoveAbandonedOnMaintenance()}
-     *
-     * @return {@link BasicDataSource#getRemoveAbandonedOnMaintenance()}
-     */
-    boolean getRemoveAbandonedOnMaintenance();
-
-    /**
-     * See {@link BasicDataSource#getRemoveAbandonedTimeout()}
-     *
-     * @return {@link BasicDataSource#getRemoveAbandonedTimeout()}
-     */
-    int getRemoveAbandonedTimeout();
-
-    /**
-     * See {@link BasicDataSource#getLogAbandoned()}
-     *
-     * @return {@link BasicDataSource#getLogAbandoned()}
-     */
-    boolean getLogAbandoned();
-
-    /**
-     * See {@link BasicDataSource#isClosed()}
-     *
-     * @return {@link BasicDataSource#isClosed()}
-     */
-    boolean isClosed();
-
-    /**
-     * See {@link BasicDataSource#getFastFailValidation()}
-     *
-     * @return {@link BasicDataSource#getFastFailValidation()}
-     * @since 2.1
-     */
-    boolean getFastFailValidation();
-
-    /**
-     * See {@link BasicDataSource#getDisconnectionSqlCodesAsArray()}
-     *
-     * @return {@link BasicDataSource#getDisconnectionSqlCodesAsArray()}
-     * @since 2.1
-     */
-    String[] getDisconnectionSqlCodesAsArray();
-
-    /**
-     * See {@link BasicDataSource#start()}
-     *
-     * @throws SQLException if an error occurs initializing the datasource
-     *
-     * @since 2.8.0
-     */
-    void start() throws SQLException;
-
-    /**
-     * See {@link BasicDataSource#restart()}
-     *
-     * @throws SQLException if an error occurs initializing the datasource
-     *
-     * @since 2.8.0
-     */
-    void restart() throws SQLException;
 }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/ConnectionFactoryFactory.java b/java/org/apache/tomcat/dbcp/dbcp2/ConnectionFactoryFactory.java
index ad1e870..bd5c244 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/ConnectionFactoryFactory.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/ConnectionFactoryFactory.java
@@ -44,7 +44,7 @@ class ConnectionFactoryFactory {
         // Set up the driver connection factory we will use
         final String user = basicDataSource.getUsername();
         if (user != null) {
-            connectionProperties.put("user", user);
+            connectionProperties.put(Constants.KEY_USER, user);
         } else {
             basicDataSource.log("DBCP DataSource configured without a 'username'");
         }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/Constants.java b/java/org/apache/tomcat/dbcp/dbcp2/Constants.java
index d9278cf..da83187 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/Constants.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/Constants.java
@@ -17,7 +17,7 @@
 package org.apache.tomcat.dbcp.dbcp2;
 
 /**
- * Constants for use with JMX.
+ * Constants.
  *
  * @since 2.0
  */
@@ -31,4 +31,18 @@ public class Constants {
 
     public static final String JMX_STATEMENT_POOL_BASE_EXT = JMX_CONNECTION_BASE_EXT;
     public static final String JMX_STATEMENT_POOL_PREFIX = ",statementpool=statements";
+
+    /**
+     * JDBC properties and URL key for passwords.
+     *
+     * @since 2.9.0
+     */
+    public static final String KEY_PASSWORD = "password";
+
+    /**
+     * JDBC properties and URL key for users.
+     *
+     * @since 2.9.0
+     */
+    public static final String KEY_USER = "user";
 }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/DataSourceConnectionFactory.java b/java/org/apache/tomcat/dbcp/dbcp2/DataSourceConnectionFactory.java
index 5fdceab..3ab0a7a 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/DataSourceConnectionFactory.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/DataSourceConnectionFactory.java
@@ -106,6 +106,6 @@ public class DataSourceConnectionFactory implements ConnectionFactory {
      * @since 2.6.0
      */
     public char[] getUserPassword() {
-        return userPassword;
+        return userPassword == null ? null : userPassword.clone();
     }
 }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceMXBean.java b/java/org/apache/tomcat/dbcp/dbcp2/DataSourceMXBean.java
similarity index 61%
copy from java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceMXBean.java
copy to java/org/apache/tomcat/dbcp/dbcp2/DataSourceMXBean.java
index 8cd178d..6e10995 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceMXBean.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/DataSourceMXBean.java
@@ -19,326 +19,320 @@ package org.apache.tomcat.dbcp.dbcp2;
 import java.sql.SQLException;
 
 /**
- * Defines the methods that will be made available via JMX.
+ * Defines the methods that will be made available via
+ * <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/management/agent.html">JMX</a>.
  *
- * @since 2.0
+ * @since 2.9.0
  */
-public interface BasicDataSourceMXBean {
+public interface DataSourceMXBean {
 
     /**
-     * See {@link BasicDataSource#getAbandonedUsageTracking()}
+     * See {@link BasicDataSource#getAbandonedUsageTracking()}.
      *
      * @return {@link BasicDataSource#getAbandonedUsageTracking()}
      */
     boolean getAbandonedUsageTracking();
 
     /**
-     * See {@link BasicDataSource#getDefaultAutoCommit()}
+     * See {@link BasicDataSource#getCacheState()}.
      *
-     * @return {@link BasicDataSource#getDefaultAutoCommit()}
+     * @return {@link BasicDataSource#getCacheState()}.
      */
-    Boolean getDefaultAutoCommit();
+    boolean getCacheState();
 
     /**
-     * See {@link BasicDataSource#getDefaultReadOnly()}
+     * See {@link BasicDataSource#getConnectionInitSqlsAsArray()}.
      *
-     * @return {@link BasicDataSource#getDefaultReadOnly()}
+     * @return {@link BasicDataSource#getConnectionInitSqlsAsArray()}.
      */
-    Boolean getDefaultReadOnly();
+    String[] getConnectionInitSqlsAsArray();
 
     /**
-     * See {@link BasicDataSource#getDefaultTransactionIsolation()}
+     * See {@link BasicDataSource#getDefaultAutoCommit()}.
      *
-     * @return {@link BasicDataSource#getDefaultTransactionIsolation()}
+     * @return {@link BasicDataSource#getDefaultAutoCommit()}.
      */
-    int getDefaultTransactionIsolation();
+    Boolean getDefaultAutoCommit();
 
     /**
-     * See {@link BasicDataSource#getDefaultCatalog()}
+     * See {@link BasicDataSource#getDefaultCatalog()}.
      *
-     * @return {@link BasicDataSource#getDefaultCatalog()}
+     * @return {@link BasicDataSource#getDefaultCatalog()}.
      */
     String getDefaultCatalog();
 
     /**
-     * See {@link BasicDataSource#getDefaultSchema()}
-     *
-     * @return {@link BasicDataSource#getDefaultSchema()}
-     * @since 2.5.0
-     */
-    String getDefaultSchema();
-
-    /**
-     * See {@link BasicDataSource#getCacheState()}
+     * See {@link BasicDataSource#getDefaultReadOnly()}.
      *
-     * @return {@link BasicDataSource#getCacheState()}
+     * @return {@link BasicDataSource#getDefaultReadOnly()}.
      */
-    boolean getCacheState();
+    Boolean getDefaultReadOnly();
 
     /**
-     * See {@link BasicDataSource#getDriverClassName()}
+     * See {@link BasicDataSource#getDefaultSchema()}.
      *
-     * @return {@link BasicDataSource#getDriverClassName()}
+     * @return {@link BasicDataSource#getDefaultSchema()}.
+     * @since 2.5.0
      */
-    String getDriverClassName();
+    String getDefaultSchema();
 
     /**
-     * See {@link BasicDataSource#getLifo()}
+     * See {@link BasicDataSource#getDefaultTransactionIsolation()}.
      *
-     * @return {@link BasicDataSource#getLifo()}
+     * @return {@link BasicDataSource#getDefaultTransactionIsolation()}.
      */
-    boolean getLifo();
+    int getDefaultTransactionIsolation();
 
     /**
-     * See {@link BasicDataSource#getMaxTotal()}
+     * See {@link BasicDataSource#getDisconnectionSqlCodesAsArray()}.
      *
-     * @return {@link BasicDataSource#getMaxTotal()}
+     * @return {@link BasicDataSource#getDisconnectionSqlCodesAsArray()}.
+     * @since 2.1
      */
-    int getMaxTotal();
+    String[] getDisconnectionSqlCodesAsArray();
 
     /**
-     * See {@link BasicDataSource#getMaxIdle()}
+     * See {@link BasicDataSource#getDriverClassName()}.
      *
-     * @return {@link BasicDataSource#getMaxIdle()}
+     * @return {@link BasicDataSource#getDriverClassName()}.
      */
-    int getMaxIdle();
+    String getDriverClassName();
 
     /**
-     * See {@link BasicDataSource#getMinIdle()}
+     * See {@link BasicDataSource#getFastFailValidation()}.
      *
-     * @return {@link BasicDataSource#getMinIdle()}
+     * @return {@link BasicDataSource#getFastFailValidation()}.
+     * @since 2.1
      */
-    int getMinIdle();
+    boolean getFastFailValidation();
 
     /**
-     * See {@link BasicDataSource#getInitialSize()}
+     * See {@link BasicDataSource#getInitialSize()}.
      *
-     * @return {@link BasicDataSource#getInitialSize()}
+     * @return {@link BasicDataSource#getInitialSize()}.
      */
     int getInitialSize();
 
     /**
-     * See {@link BasicDataSource#getMaxWaitMillis()}
+     * See {@link BasicDataSource#getLifo()}.
      *
-     * @return {@link BasicDataSource#getMaxWaitMillis()}
+     * @return {@link BasicDataSource#getLifo()}.
      */
-    long getMaxWaitMillis();
+    boolean getLifo();
 
     /**
-     * See {@link BasicDataSource#isPoolPreparedStatements()}
+     * See {@link BasicDataSource#getLogAbandoned()}.
      *
-     * @return {@link BasicDataSource#isPoolPreparedStatements()}
+     * @return {@link BasicDataSource#getLogAbandoned()}.
      */
-    boolean isPoolPreparedStatements();
+    boolean getLogAbandoned();
 
     /**
-     * See {@link BasicDataSource#isClearStatementPoolOnReturn()}
+     * See {@link BasicDataSource#getLogExpiredConnections()}.
      *
-     * @return {@link BasicDataSource#isClearStatementPoolOnReturn()}
-     * @since 2.8.0
+     * @return {@link BasicDataSource#getLogExpiredConnections()}.
+     * @since 2.1
      */
-    boolean isClearStatementPoolOnReturn();
+    boolean getLogExpiredConnections();
 
     /**
-     * See {@link BasicDataSource#getMaxOpenPreparedStatements()}
+     * See {@link BasicDataSource#getMaxConnLifetimeMillis()}.
      *
-     * @return {@link BasicDataSource#getMaxOpenPreparedStatements()}
+     * @return {@link BasicDataSource#getMaxConnLifetimeMillis()}.
      */
-    int getMaxOpenPreparedStatements();
+    long getMaxConnLifetimeMillis();
 
     /**
-     * See {@link BasicDataSource#getTestOnCreate()}
+     * See {@link BasicDataSource#getMaxIdle()}.
      *
-     * @return {@link BasicDataSource#getTestOnCreate()}
+     * @return {@link BasicDataSource#getMaxIdle()}.
      */
-    boolean getTestOnCreate();
+    int getMaxIdle();
 
     /**
-     * See {@link BasicDataSource#getTestOnBorrow()}
+     * See {@link BasicDataSource#getMaxOpenPreparedStatements()}.
      *
-     * @return {@link BasicDataSource#getTestOnBorrow()}
+     * @return {@link BasicDataSource#getMaxOpenPreparedStatements()}.
      */
-    boolean getTestOnBorrow();
+    int getMaxOpenPreparedStatements();
 
     /**
-     * See {@link BasicDataSource#getTimeBetweenEvictionRunsMillis()}
+     * See {@link BasicDataSource#getMaxTotal()}.
      *
-     * @return {@link BasicDataSource#getTimeBetweenEvictionRunsMillis()}
+     * @return {@link BasicDataSource#getMaxTotal()}.
      */
-    long getTimeBetweenEvictionRunsMillis();
+    int getMaxTotal();
 
     /**
-     * See {@link BasicDataSource#getNumTestsPerEvictionRun()}
+     * See {@link BasicDataSource#getMaxWaitMillis()}.
      *
-     * @return {@link BasicDataSource#getNumTestsPerEvictionRun()}
+     * @return {@link BasicDataSource#getMaxWaitMillis()}.
      */
-    int getNumTestsPerEvictionRun();
+    long getMaxWaitMillis();
 
     /**
-     * See {@link BasicDataSource#getMinEvictableIdleTimeMillis()}
+     * See {@link BasicDataSource#getMinEvictableIdleTimeMillis()}.
      *
-     * @return {@link BasicDataSource#getMinEvictableIdleTimeMillis()}
+     * @return {@link BasicDataSource#getMinEvictableIdleTimeMillis()}.
      */
     long getMinEvictableIdleTimeMillis();
 
     /**
-     * See {@link BasicDataSource#getSoftMinEvictableIdleTimeMillis()}
+     * See {@link BasicDataSource#getMinIdle()}.
      *
-     * @return {@link BasicDataSource#getSoftMinEvictableIdleTimeMillis()}
+     * @return {@link BasicDataSource#getMinIdle()}.
      */
-    long getSoftMinEvictableIdleTimeMillis();
+    int getMinIdle();
 
     /**
-     * See {@link BasicDataSource#getTestWhileIdle()}
+     * See {@link BasicDataSource#getNumActive()}.
      *
-     * @return {@link BasicDataSource#getTestWhileIdle()}
+     * @return {@link BasicDataSource#getNumActive()}.
      */
-    boolean getTestWhileIdle();
+    int getNumActive();
 
     /**
-     * See {@link BasicDataSource#getNumActive()}
+     * See {@link BasicDataSource#getNumIdle()}.
      *
-     * @return {@link BasicDataSource#getNumActive()}
+     * @return {@link BasicDataSource#getNumIdle()}.
      */
-    int getNumActive();
+    int getNumIdle();
 
     /**
-     * See {@link BasicDataSource#getNumIdle()}
+     * See {@link BasicDataSource#getNumTestsPerEvictionRun()}.
      *
-     * @return {@link BasicDataSource#getNumIdle()}
+     * @return {@link BasicDataSource#getNumTestsPerEvictionRun()}.
      */
-    int getNumIdle();
+    int getNumTestsPerEvictionRun();
 
     /**
-     * See {@link BasicDataSource#getPassword()}
+     * See {@link BasicDataSource#getRemoveAbandonedOnBorrow()}.
      *
-     * @return {@link BasicDataSource#getPassword()}
+     * @return {@link BasicDataSource#getRemoveAbandonedOnBorrow()}.
      */
-    String getPassword();
+    boolean getRemoveAbandonedOnBorrow();
 
     /**
-     * See {@link BasicDataSource#getUrl()}
+     * See {@link BasicDataSource#getRemoveAbandonedOnMaintenance()}.
      *
-     * @return {@link BasicDataSource#getUrl()}
+     * @return {@link BasicDataSource#getRemoveAbandonedOnMaintenance()}.
      */
-    String getUrl();
+    boolean getRemoveAbandonedOnMaintenance();
 
     /**
-     * See {@link BasicDataSource#getUsername()}
+     * See {@link BasicDataSource#getRemoveAbandonedTimeout()}.
      *
-     * @return {@link BasicDataSource#getUsername()}
+     * @return {@link BasicDataSource#getRemoveAbandonedTimeout()}.
      */
-    String getUsername();
+    int getRemoveAbandonedTimeout();
 
     /**
-     * See {@link BasicDataSource#getValidationQuery()}
+     * See {@link BasicDataSource#getSoftMinEvictableIdleTimeMillis()}.
      *
-     * @return {@link BasicDataSource#getValidationQuery()}
+     * @return {@link BasicDataSource#getSoftMinEvictableIdleTimeMillis()}.
      */
-    String getValidationQuery();
+    long getSoftMinEvictableIdleTimeMillis();
 
     /**
-     * See {@link BasicDataSource#getValidationQueryTimeout()}
+     * See {@link BasicDataSource#getTestOnBorrow()}.
      *
-     * @return {@link BasicDataSource#getValidationQueryTimeout()}
+     * @return {@link BasicDataSource#getTestOnBorrow()}.
      */
-    int getValidationQueryTimeout();
+    boolean getTestOnBorrow();
 
     /**
-     * See {@link BasicDataSource#getConnectionInitSqlsAsArray()}
+     * See {@link BasicDataSource#getTestOnCreate()}.
      *
-     * @return {@link BasicDataSource#getConnectionInitSqlsAsArray()}
+     * @return {@link BasicDataSource#getTestOnCreate()}.
      */
-    String[] getConnectionInitSqlsAsArray();
+    boolean getTestOnCreate();
 
     /**
-     * See {@link BasicDataSource#isAccessToUnderlyingConnectionAllowed()}
+     * See {@link BasicDataSource#getTestWhileIdle()}.
      *
-     * @return {@link BasicDataSource#isAccessToUnderlyingConnectionAllowed()}
+     * @return {@link BasicDataSource#getTestWhileIdle()}.
      */
-    boolean isAccessToUnderlyingConnectionAllowed();
+    boolean getTestWhileIdle();
 
     /**
-     * See {@link BasicDataSource#getMaxConnLifetimeMillis()}
+     * See {@link BasicDataSource#getTimeBetweenEvictionRunsMillis()}.
      *
-     * @return {@link BasicDataSource#getMaxConnLifetimeMillis()}
+     * @return {@link BasicDataSource#getTimeBetweenEvictionRunsMillis()}.
      */
-    long getMaxConnLifetimeMillis();
+    long getTimeBetweenEvictionRunsMillis();
 
     /**
-     * See {@link BasicDataSource#getLogExpiredConnections()}
+     * See {@link BasicDataSource#getUrl()}.
      *
-     * @return {@link BasicDataSource#getLogExpiredConnections()}
-     * @since 2.1
+     * @return {@link BasicDataSource#getUrl()}.
      */
-    boolean getLogExpiredConnections();
+    String getUrl();
 
     /**
-     * See {@link BasicDataSource#getRemoveAbandonedOnBorrow()}
+     * See {@link BasicDataSource#getUsername()}.
      *
-     * @return {@link BasicDataSource#getRemoveAbandonedOnBorrow()}
+     * @return {@link BasicDataSource#getUsername()}.
      */
-    boolean getRemoveAbandonedOnBorrow();
+    String getUsername();
 
     /**
-     * See {@link BasicDataSource#getRemoveAbandonedOnMaintenance()}
+     * See {@link BasicDataSource#getValidationQuery()}.
      *
-     * @return {@link BasicDataSource#getRemoveAbandonedOnMaintenance()}
+     * @return {@link BasicDataSource#getValidationQuery()}.
      */
-    boolean getRemoveAbandonedOnMaintenance();
+    String getValidationQuery();
 
     /**
-     * See {@link BasicDataSource#getRemoveAbandonedTimeout()}
+     * See {@link BasicDataSource#getValidationQueryTimeout()}.
      *
-     * @return {@link BasicDataSource#getRemoveAbandonedTimeout()}
+     * @return {@link BasicDataSource#getValidationQueryTimeout()}.
      */
-    int getRemoveAbandonedTimeout();
+    int getValidationQueryTimeout();
 
     /**
-     * See {@link BasicDataSource#getLogAbandoned()}
+     * See {@link BasicDataSource#isAccessToUnderlyingConnectionAllowed()}.
      *
-     * @return {@link BasicDataSource#getLogAbandoned()}
+     * @return {@link BasicDataSource#isAccessToUnderlyingConnectionAllowed()}.
      */
-    boolean getLogAbandoned();
+    boolean isAccessToUnderlyingConnectionAllowed();
 
     /**
-     * See {@link BasicDataSource#isClosed()}
+     * See {@link BasicDataSource#isClearStatementPoolOnReturn()}.
      *
-     * @return {@link BasicDataSource#isClosed()}
+     * @return {@link BasicDataSource#isClearStatementPoolOnReturn()}.
+     * @since 2.8.0
      */
-    boolean isClosed();
+    boolean isClearStatementPoolOnReturn();
 
     /**
-     * See {@link BasicDataSource#getFastFailValidation()}
+     * See {@link BasicDataSource#isClosed()}.
      *
-     * @return {@link BasicDataSource#getFastFailValidation()}
-     * @since 2.1
+     * @return {@link BasicDataSource#isClosed()}.
      */
-    boolean getFastFailValidation();
+    boolean isClosed();
 
     /**
-     * See {@link BasicDataSource#getDisconnectionSqlCodesAsArray()}
+     * See {@link BasicDataSource#isPoolPreparedStatements()}.
      *
-     * @return {@link BasicDataSource#getDisconnectionSqlCodesAsArray()}
-     * @since 2.1
+     * @return {@link BasicDataSource#isPoolPreparedStatements()}.
      */
-    String[] getDisconnectionSqlCodesAsArray();
+    boolean isPoolPreparedStatements();
 
     /**
-     * See {@link BasicDataSource#start()}
+     * See {@link BasicDataSource#restart()}
      *
-     * @throws SQLException if an error occurs initializing the datasource
+     * @throws SQLException if an error occurs initializing the data source.
      *
      * @since 2.8.0
      */
-    void start() throws SQLException;
+    void restart() throws SQLException;
 
     /**
-     * See {@link BasicDataSource#restart()}
+     * See {@link BasicDataSource#start()}
      *
-     * @throws SQLException if an error occurs initializing the datasource
+     * @throws SQLException if an error occurs initializing the data source.
      *
      * @since 2.8.0
      */
-    void restart() throws SQLException;
+    void start() throws SQLException;
 }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingConnection.java b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingConnection.java
index c036329..783c61a 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingConnection.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingConnection.java
@@ -238,6 +238,12 @@ public class DelegatingConnection<C extends Connection> extends AbandonedTrace i
         }
     }
 
+    /**
+     * Handles the given exception by throwing it.
+     * 
+     * @param e the exception to throw.
+     * @throws SQLException the exception to throw.
+     */
     protected void handleException(final SQLException e) throws SQLException {
         throw e;
     }
@@ -794,22 +800,22 @@ public class DelegatingConnection<C extends Connection> extends AbandonedTrace i
     public boolean isWrapperFor(final Class<?> iface) throws SQLException {
         if (iface.isAssignableFrom(getClass())) {
             return true;
-        } else if (iface.isAssignableFrom(connection.getClass())) {
+        }
+        if (iface.isAssignableFrom(connection.getClass())) {
             return true;
-        } else {
-            return connection.isWrapperFor(iface);
         }
+        return connection.isWrapperFor(iface);
     }
 
     @Override
     public <T> T unwrap(final Class<T> iface) throws SQLException {
         if (iface.isAssignableFrom(getClass())) {
             return iface.cast(this);
-        } else if (iface.isAssignableFrom(connection.getClass())) {
+        }
+        if (iface.isAssignableFrom(connection.getClass())) {
             return iface.cast(connection);
-        } else {
-            return connection.unwrap(iface);
         }
+        return connection.unwrap(iface);
     }
 
     @Override
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingDatabaseMetaData.java b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingDatabaseMetaData.java
index 571187a..2f34357 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingDatabaseMetaData.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingDatabaseMetaData.java
@@ -971,11 +971,10 @@ public class DelegatingDatabaseMetaData implements DatabaseMetaData {
     }
 
     protected void handleException(final SQLException e) throws SQLException {
-        if (connection != null) {
-            connection.handleException(e);
-        } else {
+        if (connection == null) {
             throw e;
         }
+        connection.handleException(e);
     }
 
     @Override
@@ -1012,11 +1011,11 @@ public class DelegatingDatabaseMetaData implements DatabaseMetaData {
     public boolean isWrapperFor(final Class<?> iface) throws SQLException {
         if (iface.isAssignableFrom(getClass())) {
             return true;
-        } else if (iface.isAssignableFrom(databaseMetaData.getClass())) {
+        }
+        if (iface.isAssignableFrom(databaseMetaData.getClass())) {
             return true;
-        } else {
-            return databaseMetaData.isWrapperFor(iface);
         }
+        return databaseMetaData.isWrapperFor(iface);
     }
 
     @Override
@@ -1779,8 +1778,6 @@ public class DelegatingDatabaseMetaData implements DatabaseMetaData {
         }
     }
 
-    /* JDBC_4_ANT_KEY_BEGIN */
-
     @Override
     public boolean supportsSubqueriesInComparisons() throws SQLException {
         try {
@@ -1877,11 +1874,11 @@ public class DelegatingDatabaseMetaData implements DatabaseMetaData {
     public <T> T unwrap(final Class<T> iface) throws SQLException {
         if (iface.isAssignableFrom(getClass())) {
             return iface.cast(this);
-        } else if (iface.isAssignableFrom(databaseMetaData.getClass())) {
+        }
+        if (iface.isAssignableFrom(databaseMetaData.getClass())) {
             return iface.cast(databaseMetaData);
-        } else {
-            return databaseMetaData.unwrap(iface);
         }
+        return databaseMetaData.unwrap(iface);
     }
 
     @Override
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingResultSet.java b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingResultSet.java
index ab6ca10..c238223 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingResultSet.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingResultSet.java
@@ -101,15 +101,15 @@ public final class DelegatingResultSet extends AbandonedTrace implements ResultS
      * Private to ensure all construction is {@link #wrapResultSet(Connection, ResultSet)}
      * </p>
      *
-     * @param conn
+     * @param connection
      *            Connection which created this ResultSet
-     * @param res
+     * @param resultSet
      *            ResultSet to wrap
      */
-    private DelegatingResultSet(final Connection conn, final ResultSet res) {
-        super((AbandonedTrace) conn);
-        this.connection = conn;
-        this.resultSet = res;
+    private DelegatingResultSet(final Connection connection, final ResultSet resultSet) {
+        super((AbandonedTrace) connection);
+        this.connection = connection;
+        this.resultSet = resultSet;
     }
 
     /**
@@ -1116,11 +1116,11 @@ public final class DelegatingResultSet extends AbandonedTrace implements ResultS
     public boolean isWrapperFor(final Class<?> iface) throws SQLException {
         if (iface.isAssignableFrom(getClass())) {
             return true;
-        } else if (iface.isAssignableFrom(resultSet.getClass())) {
+        }
+        if (iface.isAssignableFrom(resultSet.getClass())) {
             return true;
-        } else {
-            return resultSet.isWrapperFor(iface);
         }
+        return resultSet.isWrapperFor(iface);
     }
 
     @Override
@@ -1247,11 +1247,11 @@ public final class DelegatingResultSet extends AbandonedTrace implements ResultS
     public <T> T unwrap(final Class<T> iface) throws SQLException {
         if (iface.isAssignableFrom(getClass())) {
             return iface.cast(this);
-        } else if (iface.isAssignableFrom(resultSet.getClass())) {
+        }
+        if (iface.isAssignableFrom(resultSet.getClass())) {
             return iface.cast(resultSet);
-        } else {
-            return resultSet.unwrap(iface);
         }
+        return resultSet.unwrap(iface);
     }
 
     @Override
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingStatement.java b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingStatement.java
index 770680e..9a2630e 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingStatement.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingStatement.java
@@ -43,7 +43,7 @@ public class DelegatingStatement extends AbandonedTrace implements Statement {
     /** The connection that created me. **/
     private DelegatingConnection<?> connection;
 
-    private boolean closed = false;
+    private boolean closed;
 
     /**
      * Create a wrapper for the Statement which traces this Statement to the Connection which created it and the code
@@ -521,11 +521,10 @@ public class DelegatingStatement extends AbandonedTrace implements Statement {
     }
 
     protected void handleException(final SQLException e) throws SQLException {
-        if (connection != null) {
-            connection.handleException(e);
-        } else {
+        if (connection == null) {
             throw e;
         }
+        connection.handleException(e);
     }
 
     /*
@@ -566,11 +565,11 @@ public class DelegatingStatement extends AbandonedTrace implements Statement {
     public boolean isWrapperFor(final Class<?> iface) throws SQLException {
         if (iface.isAssignableFrom(getClass())) {
             return true;
-        } else if (iface.isAssignableFrom(statement.getClass())) {
+        }
+        if (iface.isAssignableFrom(statement.getClass())) {
             return true;
-        } else {
-            return statement.isWrapperFor(iface);
         }
+        return statement.isWrapperFor(iface);
     }
 
     /**
@@ -699,10 +698,10 @@ public class DelegatingStatement extends AbandonedTrace implements Statement {
     public <T> T unwrap(final Class<T> iface) throws SQLException {
         if (iface.isAssignableFrom(getClass())) {
             return iface.cast(this);
-        } else if (iface.isAssignableFrom(statement.getClass())) {
+        }
+        if (iface.isAssignableFrom(statement.getClass())) {
             return iface.cast(statement);
-        } else {
-            return statement.unwrap(iface);
         }
+        return statement.unwrap(iface);
     }
 }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/PStmtKey.java b/java/org/apache/tomcat/dbcp/dbcp2/PStmtKey.java
index 3b5daf3..87991e7 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/PStmtKey.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/PStmtKey.java
@@ -852,7 +852,7 @@ public class PStmtKey {
      * @return An array of column indexes.
      */
     public int[] getColumnIndexes() {
-        return columnIndexes;
+        return columnIndexes == null ? null : columnIndexes.clone();
     }
 
     /**
@@ -861,7 +861,7 @@ public class PStmtKey {
      * @return An array of column names.
      */
     public String[] getColumnNames() {
-        return columnNames;
+        return columnNames == null ? null : columnNames.clone();
     }
 
     /**
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnection.java b/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnection.java
index 6b052ce..101b511 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnection.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnection.java
@@ -64,7 +64,7 @@ public class PoolableConnection extends DelegatingConnection<Connection> impleme
      * Indicate that unrecoverable SQLException was thrown when using this connection. Such a connection should be
      * considered broken and not pass validation in the future.
      */
-    private boolean fatalSqlExceptionThrown = false;
+    private boolean fatalSqlExceptionThrown;
 
     /**
      * SQL_STATE codes considered to signal fatal conditions. Overrides the defaults in
@@ -240,7 +240,7 @@ public class PoolableConnection extends DelegatingConnection<Connection> impleme
      * @since 2.9.0
      */
     @Override
-    public void abort(Executor executor) throws SQLException {
+    public void abort(final Executor executor) throws SQLException {
         if (jmxObjectName != null) {
             jmxObjectName.unregisterMBean();
         }
@@ -278,7 +278,7 @@ public class PoolableConnection extends DelegatingConnection<Connection> impleme
             throw new SQLException(Utils.getMessage("poolableConnection.validate.fastFail"));
         }
 
-        if (sql == null || sql.length() == 0) {
+        if (sql == null || sql.isEmpty()) {
             if (timeoutSeconds < 0) {
                 timeoutSeconds = 0;
             }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionFactory.java b/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionFactory.java
index 3edf0d2..8b4cf74 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionFactory.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionFactory.java
@@ -654,10 +654,10 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
 
     private void validateLifetime(final PooledObject<PoolableConnection> p) throws Exception {
         if (maxConnLifetimeMillis > 0) {
-            final long lifetime = System.currentTimeMillis() - p.getCreateTime();
-            if (lifetime > maxConnLifetimeMillis) {
+            final long lifetimeMillis = System.currentTimeMillis() - p.getCreateTime();
+            if (lifetimeMillis > maxConnLifetimeMillis) {
                 throw new LifetimeExceededException(Utils.getMessage("connectionFactory.lifetimeExceeded",
-                        Long.valueOf(lifetime), Long.valueOf(maxConnLifetimeMillis)));
+                        Long.valueOf(lifetimeMillis), Long.valueOf(maxConnLifetimeMillis)));
             }
         }
     }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/PoolablePreparedStatement.java b/java/org/apache/tomcat/dbcp/dbcp2/PoolablePreparedStatement.java
index 32b63aa..e0b079c 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/PoolablePreparedStatement.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/PoolablePreparedStatement.java
@@ -49,7 +49,7 @@ public class PoolablePreparedStatement<K> extends DelegatingPreparedStatement {
      */
     private final K key;
 
-    private volatile boolean batchAdded = false;
+    private volatile boolean batchAdded;
 
     /**
      * Constructor.
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java b/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java
index 54ce6e0..18818a3 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java
@@ -65,7 +65,7 @@ public class PoolingConnection extends DelegatingConnection<Connection>
     /** Pool of {@link PreparedStatement}s. and {@link CallableStatement}s */
     private KeyedObjectPool<PStmtKey, DelegatingPreparedStatement> pstmtPool;
 
-    private boolean clearStatementPoolOnReturn = false;
+    private boolean clearStatementPoolOnReturn;
 
     /**
      * Constructor.
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/PoolingDataSource.java b/java/org/apache/tomcat/dbcp/dbcp2/PoolingDataSource.java
index 5f0ca20..37b9961 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/PoolingDataSource.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/PoolingDataSource.java
@@ -105,15 +105,17 @@ public class PoolingDataSource<C extends Connection> implements DataSource, Auto
         this.accessToUnderlyingConnectionAllowed = allow;
     }
 
-    /* JDBC_4_ANT_KEY_BEGIN */
     @Override
     public boolean isWrapperFor(final Class<?> iface) throws SQLException {
-        return false;
+        return iface != null && iface.isInstance(this);
     }
 
     @Override
     public <T> T unwrap(final Class<T> iface) throws SQLException {
-        throw new SQLException("PoolingDataSource is not a wrapper.");
+        if (isWrapperFor(iface)) {
+            return iface.cast(this);
+        }
+        throw new SQLException(this + " is not a wrapper for " + iface);
     }
     /* JDBC_4_ANT_KEY_END */
 
@@ -204,7 +206,7 @@ public class PoolingDataSource<C extends Connection> implements DataSource, Auto
     }
 
     /** My log writer. */
-    private PrintWriter logWriter = null;
+    private PrintWriter logWriter;
 
     private final ObjectPool<C> pool;
 
@@ -249,7 +251,7 @@ public class PoolingDataSource<C extends Connection> implements DataSource, Auto
 
         @Override
         public boolean isClosed() throws SQLException {
-            return getDelegateInternal() == null ? true : super.isClosed();
+            return getDelegateInternal() == null || super.isClosed();
         }
     }
 }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/PoolingDriver.java b/java/org/apache/tomcat/dbcp/dbcp2/PoolingDriver.java
index 67b4c4d..bf314ca 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/PoolingDriver.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/PoolingDriver.java
@@ -36,7 +36,7 @@ import org.apache.tomcat.dbcp.pool2.ObjectPool;
  */
 public class PoolingDriver implements Driver {
 
-    private static final DriverPropertyInfo[] EMPTY_DRIVER_PROPERTY_INFO_ARRAY = new DriverPropertyInfo[0];
+    private static final DriverPropertyInfo[] EMPTY_DRIVER_PROPERTY_INFO_ARRAY = {};
 
     /* Register myself with the {@link DriverManager}. */
     static {
@@ -179,18 +179,17 @@ public class PoolingDriver implements Driver {
      *             the connection
      */
     public void invalidateConnection(final Connection conn) throws SQLException {
-        if (conn instanceof PoolGuardConnectionWrapper) { // normal case
-            final PoolGuardConnectionWrapper pgconn = (PoolGuardConnectionWrapper) conn;
-            @SuppressWarnings("unchecked")
-            final ObjectPool<Connection> pool = (ObjectPool<Connection>) pgconn.pool;
-            try {
-                pool.invalidateObject(pgconn.getDelegateInternal());
-            } catch (final Exception e) {
-                // Ignore.
-            }
-        } else {
+        if (!(conn instanceof PoolGuardConnectionWrapper)) {
             throw new SQLException("Invalid connection class");
         }
+        final PoolGuardConnectionWrapper pgconn = (PoolGuardConnectionWrapper) conn;
+        @SuppressWarnings("unchecked")
+        final ObjectPool<Connection> pool = (ObjectPool<Connection>) pgconn.pool;
+        try {
+            pool.invalidateObject(pgconn.getDelegateInternal());
+        } catch (final Exception e) {
+            // Ignore.
+        }
     }
 
     @Override
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/Utils.java b/java/org/apache/tomcat/dbcp/dbcp2/Utils.java
index c0ebadb..1764edb 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/Utils.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/Utils.java
@@ -55,8 +55,8 @@ 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 final ResultSet[] EMPTY_RESULT_SET_ARRAY = {};
+    static final String[] EMPTY_STRING_ARRAY = {};
 
     static {
         DISCONNECTION_SQL_CODES = new HashSet<>();
@@ -88,8 +88,8 @@ public final class Utils {
     public static Properties cloneWithoutCredentials(final Properties properties) {
         if (properties != null) {
             final Properties temp = (Properties) properties.clone();
-            temp.remove("user");
-            temp.remove("password");
+            temp.remove(Constants.KEY_USER);
+            temp.remove(Constants.KEY_PASSWORD);
             return temp;
         }
         return properties;
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java b/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java
index 399114f..203151f 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java
@@ -37,6 +37,7 @@ import javax.sql.ConnectionPoolDataSource;
 import javax.sql.PooledConnection;
 
 import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
+import org.apache.tomcat.dbcp.dbcp2.Constants;
 import org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement;
 import org.apache.tomcat.dbcp.dbcp2.PStmtKey;
 import org.apache.tomcat.dbcp.dbcp2.Utils;
@@ -77,10 +78,6 @@ import org.apache.tomcat.dbcp.pool2.impl.GenericKeyedObjectPoolConfig;
  */
 public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceable, Serializable, ObjectFactory {
 
-    private static final String KEY_USER = "user";
-
-    private static final String KEY_PASSWORD = "password";
-
     private static final long serialVersionUID = -4820523787212147844L;
 
     private static final String GET_CONNECTION_CALLED = "A PooledConnection was already requested from this source, "
@@ -267,11 +264,11 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
                 if (isNotEmpty(ra)) {
                     setUrl(getStringContent(ra));
                 }
-                ra = ref.get(KEY_USER);
+                ra = ref.get(Constants.KEY_USER);
                 if (isNotEmpty(ra)) {
                     setUser(getStringContent(ra));
                 }
-                ra = ref.get(KEY_PASSWORD);
+                ra = ref.get(Constants.KEY_PASSWORD);
                 if (isNotEmpty(ra)) {
                     setPassword(getStringContent(ra));
                 }
@@ -336,7 +333,7 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
      * @since 2.4.0
      */
     public char[] getPasswordCharArray() {
-        return userPassword;
+        return userPassword == null ? null : userPassword.clone();
     }
 
     /**
@@ -358,11 +355,11 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
         throws SQLException {
         getConnectionCalled = true;
         PooledConnectionImpl pooledConnection = null;
-        // Workaround for buggy WebLogic 5.1 classloader - ignore the exception upon first invocation.
+        // Workaround for buggy WebLogic 5.1 class loader - ignore the exception upon first invocation.
         try {
             if (connectionProperties != null) {
-                update(connectionProperties, KEY_USER, pooledUserName);
-                update(connectionProperties, KEY_PASSWORD, pooledUserPassword);
+                update(connectionProperties, Constants.KEY_USER, pooledUserName);
+                update(connectionProperties, Constants.KEY_PASSWORD, pooledUserPassword);
                 pooledConnection = new PooledConnectionImpl(
                     DriverManager.getConnection(getUrl(), connectionProperties));
             } else {
@@ -388,13 +385,13 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
             config.setMaxWaitMillis(0);
             config.setMaxIdlePerKey(getMaxIdle());
             if (getMaxPreparedStatements() <= 0) {
-                // since there is no limit, create a prepared statement pool with an eviction thread;
+                // Since there is no limit, create a prepared statement pool with an eviction thread;
                 // evictor settings are the same as the connection pool settings.
                 config.setTimeBetweenEvictionRunsMillis(getTimeBetweenEvictionRunsMillis());
                 config.setNumTestsPerEvictionRun(getNumTestsPerEvictionRun());
                 config.setMinEvictableIdleTimeMillis(getMinEvictableIdleTimeMillis());
             } else {
-                // since there is a limit, create a prepared statement pool without an eviction thread;
+                // Since there is a limit, create a prepared statement pool without an eviction thread;
                 // pool has LRU functionality so when the limit is reached, 15% of the pool is cleared.
                 // see org.apache.commons.pool2.impl.GenericKeyedObjectPool.clearOldest method
                 config.setMaxTotal(getMaxPreparedStatements());
@@ -421,8 +418,8 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
         ref.add(new StringRefAddr("description", getDescription()));
         ref.add(new StringRefAddr("driver", getDriver()));
         ref.add(new StringRefAddr("loginTimeout", String.valueOf(getLoginTimeout())));
-        ref.add(new StringRefAddr(KEY_PASSWORD, getPassword()));
-        ref.add(new StringRefAddr(KEY_USER, getUser()));
+        ref.add(new StringRefAddr(Constants.KEY_PASSWORD, getPassword()));
+        ref.add(new StringRefAddr(Constants.KEY_USER, getUser()));
         ref.add(new StringRefAddr("url", getUrl()));
 
         ref.add(new StringRefAddr("poolPreparedStatements", String.valueOf(isPoolPreparedStatements())));
@@ -518,11 +515,11 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
         assertInitializationAllowed();
         connectionProperties = props;
         if (connectionProperties != null) {
-            if (connectionProperties.containsKey(KEY_USER)) {
-                setUser(connectionProperties.getProperty(KEY_USER));
+            if (connectionProperties.containsKey(Constants.KEY_USER)) {
+                setUser(connectionProperties.getProperty(Constants.KEY_USER));
             }
-            if (connectionProperties.containsKey(KEY_PASSWORD)) {
-                setPassword(connectionProperties.getProperty(KEY_PASSWORD));
+            if (connectionProperties.containsKey(Constants.KEY_PASSWORD)) {
+                setPassword(connectionProperties.getProperty(Constants.KEY_PASSWORD));
             }
         }
     }
@@ -531,25 +528,25 @@ 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 description Value to assign to description.
      */
-    public void setDescription(final String v) {
-        this.description = v;
+    public void setDescription(final String description) {
+        this.description = description;
     }
 
     /**
      * 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.
+     * @param driver 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 {
+    public void setDriver(final String driver) throws ClassNotFoundException {
         assertInitializationAllowed();
-        this.driver = v;
+        this.driver = driver;
         // make sure driver is registered
-        Class.forName(v);
+        Class.forName(driver);
     }
 
     /**
@@ -558,15 +555,15 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
      */
     @Override
     public void setLoginTimeout(final int seconds) {
-        loginTimeout = seconds;
+        this.loginTimeout = seconds;
     }
 
     /**
      * Sets the log writer for this data source. NOT USED.
      */
     @Override
-    public void setLogWriter(final PrintWriter out) {
-        logWriter = out;
+    public void setLogWriter(final PrintWriter logWriter) {
+        this.logWriter = logWriter;
     }
 
     /**
@@ -631,7 +628,7 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
     public void setPassword(final char[] userPassword) {
         assertInitializationAllowed();
         this.userPassword = Utils.clone(userPassword);
-        update(connectionProperties, KEY_PASSWORD, Utils.toString(this.userPassword));
+        update(connectionProperties, Constants.KEY_PASSWORD, Utils.toString(this.userPassword));
     }
 
     /**
@@ -643,7 +640,7 @@ public class DriverAdapterCPDS implements ConnectionPoolDataSource, Referenceabl
     public void setPassword(final String userPassword) {
         assertInitializationAllowed();
         this.userPassword = Utils.toCharArray(userPassword);
-        update(connectionProperties, KEY_PASSWORD, userPassword);
+        update(connectionProperties, Constants.KEY_PASSWORD, userPassword);
     }
 
     /**
@@ -674,24 +671,24 @@ 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.
+     * @param url Value to assign to url.
      * @throws IllegalStateException if {@link #getPooledConnection()} has been called
      */
-    public void setUrl(final String v) {
+    public void setUrl(final String url) {
         assertInitializationAllowed();
-        this.url = v;
+        this.url = url;
     }
 
     /**
      * Sets the value of default user (login or user name).
      *
-     * @param v Value to assign to user.
+     * @param userName Value to assign to user.
      * @throws IllegalStateException if {@link #getPooledConnection()} has been called
      */
-    public void setUser(final String v) {
+    public void setUser(final String userName) {
         assertInitializationAllowed();
-        this.userName = v;
-        update(connectionProperties, KEY_USER, v);
+        this.userName = userName;
+        update(connectionProperties, Constants.KEY_USER, userName);
     }
 
     /**
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PooledConnectionImpl.java b/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PooledConnectionImpl.java
index f249457..3bef44f 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PooledConnectionImpl.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PooledConnectionImpl.java
@@ -20,7 +20,9 @@ import java.sql.CallableStatement;
 import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.SQLException;
-import java.util.Vector;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 import javax.sql.ConnectionEvent;
 import javax.sql.ConnectionEventListener;
@@ -68,12 +70,12 @@ class PooledConnectionImpl
     /**
      * ConnectionEventListeners.
      */
-    private final Vector<ConnectionEventListener> eventListeners;
+    private final List<ConnectionEventListener> eventListeners;
 
     /**
      * StatementEventListeners.
      */
-    private final Vector<StatementEventListener> statementEventListeners = new Vector<>();
+    private final List<StatementEventListener> statementEventListeners = Collections.synchronizedList(new ArrayList<StatementEventListener>());
 
     /**
      * Flag set to true, once {@link #close()} is called.
@@ -101,7 +103,7 @@ class PooledConnectionImpl
         } else {
             this.delegatingConnection = new DelegatingConnection<>(connection);
         }
-        eventListeners = new Vector<>();
+        eventListeners = Collections.synchronizedList(new ArrayList<ConnectionEventListener>());
         closed = false;
     }
 
@@ -126,7 +128,6 @@ class PooledConnectionImpl
         }
     }
 
-    /* JDBC_4_ANT_KEY_BEGIN */
     @Override
     public void addStatementEventListener(final StatementEventListener listener) {
         if (!statementEventListeners.contains(listener)) {
@@ -699,7 +700,6 @@ class PooledConnectionImpl
         eventListeners.remove(listener);
     }
 
-    /* JDBC_4_ANT_KEY_BEGIN */
     @Override
     public void removeStatementEventListener(final StatementEventListener listener) {
         statementEventListeners.remove(listener);
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/datasources/CPDSConnectionFactory.java b/java/org/apache/tomcat/dbcp/dbcp2/datasources/CPDSConnectionFactory.java
index 6c91099..bd312f0 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/datasources/CPDSConnectionFactory.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/datasources/CPDSConnectionFactory.java
@@ -392,9 +392,9 @@ class CPDSConnectionFactory
 
     private void validateLifetime(final PooledObject<PooledConnectionAndInfo> p) throws Exception {
         if (maxConnLifetimeMillis > 0) {
-            final long lifetime = System.currentTimeMillis() - p.getCreateTime();
-            if (lifetime > maxConnLifetimeMillis) {
-                throw new Exception(Utils.getMessage("connectionFactory.lifetimeExceeded", Long.valueOf(lifetime),
+            final long lifetimeMillis = System.currentTimeMillis() - p.getCreateTime();
+            if (lifetimeMillis > maxConnLifetimeMillis) {
+                throw new Exception(Utils.getMessage("connectionFactory.lifetimeExceeded", Long.valueOf(lifetimeMillis),
                         Long.valueOf(maxConnLifetimeMillis)));
             }
         }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSource.java b/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSource.java
index 7f99a9b..9e5f5d0 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSource.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSource.java
@@ -137,7 +137,7 @@ public abstract class InstanceKeyDataSource implements DataSource, Referenceable
     private Boolean defaultReadOnly;
 
     /**
-     * Default no-arg constructor for Serialization
+     * Default no-arg constructor for Serialization.
      */
     public InstanceKeyDataSource() {
     }
@@ -161,15 +161,18 @@ public abstract class InstanceKeyDataSource implements DataSource, Referenceable
 
     protected abstract PooledConnectionManager getConnectionManager(UserPassKey upkey);
 
-    /* JDBC_4_ANT_KEY_BEGIN */
     @Override
     public boolean isWrapperFor(final Class<?> iface) throws SQLException {
-        return false;
+        return iface.isInstance(this);
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public <T> T unwrap(final Class<T> iface) throws SQLException {
-        throw new SQLException("InstanceKeyDataSource is not a wrapper.");
+        if (isWrapperFor(iface)) {
+            return (T) this;
+        }
+        throw new SQLException(this + " is not a wrapper for " + iface);
     }
     /* JDBC_4_ANT_KEY_END */
 
@@ -178,9 +181,6 @@ public abstract class InstanceKeyDataSource implements DataSource, Referenceable
         throw new SQLFeatureNotSupportedException();
     }
 
-    // -------------------------------------------------------------------
-    // Properties
-
     /**
      * Gets the default value for {@link GenericKeyedObjectPoolConfig#getBlockWhenExhausted()} for each per user pool.
      *
@@ -533,18 +533,18 @@ public abstract class InstanceKeyDataSource implements DataSource, Referenceable
      * Sets the back end ConnectionPoolDataSource. This property should not be set if using JNDI to access the
      * data source.
      *
-     * @param v
+     * @param dataSource
      *            Value to assign to connectionPoolDataSource.
      */
-    public void setConnectionPoolDataSource(final ConnectionPoolDataSource v) {
+    public void setConnectionPoolDataSource(final ConnectionPoolDataSource dataSource) {
         assertInitializationAllowed();
         if (dataSourceName != null) {
             throw new IllegalStateException("Cannot set the DataSource, if JNDI is used.");
         }
-        if (dataSource != null) {
+        if (this.dataSource != null) {
             throw new IllegalStateException("The CPDS has already been set. It cannot be altered.");
         }
-        dataSource = v;
+        this.dataSource = dataSource;
         instanceKey = InstanceKeyDataSourceFactory.registerNewInstance(this);
     }
 
@@ -562,19 +562,19 @@ public abstract class InstanceKeyDataSource implements DataSource, Referenceable
      * Sets the name of the ConnectionPoolDataSource which backs this pool. This name is used to look up the data source
      * from a JNDI service provider.
      *
-     * @param v
+     * @param dataSourceName
      *            Value to assign to dataSourceName.
      */
-    public void setDataSourceName(final String v) {
+    public void setDataSourceName(final String dataSourceName) {
         assertInitializationAllowed();
         if (dataSource != null) {
             throw new IllegalStateException("Cannot set the JNDI name for the DataSource, if already "
                     + "set using setConnectionPoolDataSource.");
         }
-        if (dataSourceName != null) {
+        if (this.dataSourceName != null) {
             throw new IllegalStateException("The DataSourceName has already been set. " + "It cannot be altered.");
         }
-        this.dataSourceName = v;
+        this.dataSourceName = dataSourceName;
         instanceKey = InstanceKeyDataSourceFactory.registerNewInstance(this);
     }
 
@@ -594,12 +594,12 @@ public abstract class InstanceKeyDataSource implements DataSource, Referenceable
      * can be changed on the Connection using Connection.setAutoCommit(boolean). The default is <code>null</code> which
      * will use the default value for the drive.
      *
-     * @param v
+     * @param defaultAutoCommit
      *            Value to assign to defaultAutoCommit.
      */
-    public void setDefaultAutoCommit(final Boolean v) {
+    public void setDefaultAutoCommit(final Boolean defaultAutoCommit) {
         assertInitializationAllowed();
-        this.defaultAutoCommit = v;
+        this.defaultAutoCommit = defaultAutoCommit;
     }
 
     /**
@@ -618,12 +618,12 @@ public abstract class InstanceKeyDataSource implements DataSource, Referenceable
      * can be changed on the Connection using Connection.setReadOnly(boolean). The default is <code>null</code> which
      * will use the default value for the drive.
      *
-     * @param v
+     * @param defaultReadOnly
      *            Value to assign to defaultReadOnly.
      */
-    public void setDefaultReadOnly(final Boolean v) {
+    public void setDefaultReadOnly(final Boolean defaultReadOnly) {
         assertInitializationAllowed();
-        this.defaultReadOnly = v;
+        this.defaultReadOnly = defaultReadOnly;
     }
 
     /**
@@ -642,12 +642,12 @@ public abstract class InstanceKeyDataSource implements DataSource, Referenceable
      * The value can be changed on the Connection using Connection.setTransactionIsolation(int). The default is JDBC
      * driver dependent.
      *
-     * @param v
+     * @param defaultTransactionIsolation
      *            Value to assign to defaultTransactionIsolation
      */
-    public void setDefaultTransactionIsolation(final int v) {
+    public void setDefaultTransactionIsolation(final int defaultTransactionIsolation) {
         assertInitializationAllowed();
-        switch (v) {
+        switch (defaultTransactionIsolation) {
         case Connection.TRANSACTION_NONE:
         case Connection.TRANSACTION_READ_COMMITTED:
         case Connection.TRANSACTION_READ_UNCOMMITTED:
@@ -657,7 +657,7 @@ public abstract class InstanceKeyDataSource implements DataSource, Referenceable
         default:
             throw new IllegalArgumentException(BAD_TRANSACTION_ISOLATION);
         }
-        this.defaultTransactionIsolation = v;
+        this.defaultTransactionIsolation = defaultTransactionIsolation;
     }
 
     /**
@@ -674,11 +674,11 @@ public abstract class InstanceKeyDataSource implements DataSource, Referenceable
      * Sets the description. This property is defined by JDBC as for use with GUI (or other) tools that might deploy the
      * datasource. It serves no internal purpose.
      *
-     * @param v
+     * @param description
      *            Value to assign to description.
      */
-    public void setDescription(final String v) {
-        this.description = v;
+    public void setDescription(final String description) {
+        this.description = description;
     }
 
     protected String getInstanceKey() {
@@ -746,12 +746,12 @@ public abstract class InstanceKeyDataSource implements DataSource, Referenceable
     /**
      * Sets the value of loginTimeout.
      *
-     * @param v
+     * @param loginTimeout
      *            Value to assign to loginTimeout.
      */
     @Override
-    public void setLoginTimeout(final int v) {
-        this.loginTimeout = v;
+    public void setLoginTimeout(final int loginTimeout) {
+        this.loginTimeout = loginTimeout;
     }
 
     /**
@@ -770,12 +770,12 @@ public abstract class InstanceKeyDataSource implements DataSource, Referenceable
     /**
      * Sets the value of logWriter.
      *
-     * @param v
+     * @param logWriter
      *            Value to assign to logWriter.
      */
     @Override
-    public void setLogWriter(final PrintWriter v) {
-        this.logWriter = v;
+    public void setLogWriter(final PrintWriter logWriter) {
+        this.logWriter = logWriter;
     }
 
     /**
@@ -876,12 +876,6 @@ public abstract class InstanceKeyDataSource implements DataSource, Referenceable
         this.maxConnLifetimeMillis = maxConnLifetimeMillis;
     }
 
-    // ----------------------------------------------------------------------
-    // Instrumentation Methods
-
-    // ----------------------------------------------------------------------
-    // DataSource implementation
-
     /**
      * Attempts to establish a database connection.
      */
@@ -1011,12 +1005,11 @@ public abstract class InstanceKeyDataSource implements DataSource, Referenceable
                 ctx = new InitialContext(jndiEnvironment);
             }
             final Object ds = ctx.lookup(dataSourceName);
-            if (ds instanceof ConnectionPoolDataSource) {
-                cpds = (ConnectionPoolDataSource) ds;
-            } else {
+            if (!(ds instanceof ConnectionPoolDataSource)) {
                 throw new SQLException("Illegal configuration: " + "DataSource " + dataSourceName + " ("
                         + ds.getClass().getName() + ")" + " doesn't implement javax.sql.ConnectionPoolDataSource");
             }
+            cpds = (ConnectionPoolDataSource) ds;
         }
 
         // try to get a connection with the supplied userName/password
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSourceFactory.java b/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSourceFactory.java
index defa46a..0c9ff46 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSourceFactory.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSourceFactory.java
@@ -42,11 +42,11 @@ import org.apache.tomcat.dbcp.dbcp2.ListException;
  */
 abstract class InstanceKeyDataSourceFactory implements ObjectFactory {
 
-    private static final Map<String, InstanceKeyDataSource> instanceMap = new ConcurrentHashMap<>();
+    private static final Map<String, InstanceKeyDataSource> INSTANCE_MAP = new ConcurrentHashMap<>();
 
     static synchronized String registerNewInstance(final InstanceKeyDataSource ds) {
         int max = 0;
-        for (final String s : instanceMap.keySet()) {
+        for (final String s : INSTANCE_MAP.keySet()) {
             if (s != null) {
                 try {
                     max = Math.max(max, Integer.parseInt(s));
@@ -58,13 +58,13 @@ abstract class InstanceKeyDataSourceFactory implements ObjectFactory {
         final String instanceKey = String.valueOf(max + 1);
         // Put a placeholder here for now, so other instances will not
         // take our key. We will replace with a pool when ready.
-        instanceMap.put(instanceKey, ds);
+        INSTANCE_MAP.put(instanceKey, ds);
         return instanceKey;
     }
 
     static void removeInstance(final String key) {
         if (key != null) {
-            instanceMap.remove(key);
+            INSTANCE_MAP.remove(key);
         }
     }
 
@@ -80,8 +80,8 @@ 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 (final Entry<String, InstanceKeyDataSource> next : instanceMap.entrySet()) {
+        final List<Throwable> exceptionList = new ArrayList<>(INSTANCE_MAP.size());
+        for (final Entry<String, InstanceKeyDataSource> next : INSTANCE_MAP.entrySet()) {
             // Bullet-proof to avoid anything else but problems from InstanceKeyDataSource#close().
             if (next != null) {
                 final InstanceKeyDataSource value = next.getValue();
@@ -94,7 +94,7 @@ abstract class InstanceKeyDataSourceFactory implements ObjectFactory {
                 }
             }
         }
-        instanceMap.clear();
+        INSTANCE_MAP.clear();
         if (!exceptionList.isEmpty()) {
             throw new ListException("Could not close all InstanceKeyDataSource instances.", exceptionList);
         }
@@ -115,7 +115,7 @@ abstract class InstanceKeyDataSourceFactory implements ObjectFactory {
                 final RefAddr refAddr = ref.get("instanceKey");
                 if (refAddr != null && refAddr.getContent() != null) {
                     // object was bound to JNDI via Referenceable API.
-                    obj = instanceMap.get(refAddr.getContent());
+                    obj = INSTANCE_MAP.get(refAddr.getContent());
                 } else {
                     // Tomcat JNDI creates a Reference out of server.xml
                     // <ResourceParam> configuration and passes it to an
@@ -123,14 +123,14 @@ abstract class InstanceKeyDataSourceFactory implements ObjectFactory {
                     String key = null;
                     if (name != null) {
                         key = name.toString();
-                        obj = instanceMap.get(key);
+                        obj = INSTANCE_MAP.get(key);
                     }
                     if (obj == null) {
                         final InstanceKeyDataSource ds = getNewInstance(ref);
                         setCommonProperties(ref, ds);
                         obj = ds;
                         if (key != null) {
-                            instanceMap.put(key, ds);
+                            INSTANCE_MAP.put(key, ds);
                         }
                     }
                 }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/datasources/KeyedCPDSConnectionFactory.java b/java/org/apache/tomcat/dbcp/dbcp2/datasources/KeyedCPDSConnectionFactory.java
index 46b3405..85364e1 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/datasources/KeyedCPDSConnectionFactory.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/datasources/KeyedCPDSConnectionFactory.java
@@ -112,24 +112,24 @@ class KeyedCPDSConnectionFactory implements KeyedPooledObjectFactory<UserPassKey
      */
     @Override
     public synchronized PooledObject<PooledConnectionAndInfo> makeObject(final UserPassKey upkey) throws Exception {
-        PooledConnection pc = null;
-        final String userName = upkey.getUsername();
+        PooledConnection pooledConnection = null;
+        final String userName = upkey.getUserName();
         final String password = upkey.getPassword();
         if (userName == null) {
-            pc = cpds.getPooledConnection();
+            pooledConnection = cpds.getPooledConnection();
         } else {
-            pc = cpds.getPooledConnection(userName, password);
+            pooledConnection = cpds.getPooledConnection(userName, password);
         }
 
-        if (pc == null) {
+        if (pooledConnection == null) {
             throw new IllegalStateException("Connection pool data source returned null from getPooledConnection");
         }
 
         // should we add this object as a listener or the pool.
         // consider the validateObject method in decision
-        pc.addConnectionEventListener(this);
-        final PooledConnectionAndInfo pci = new PooledConnectionAndInfo(pc, userName, upkey.getPasswordCharArray());
-        pcMap.put(pc, pci);
+        pooledConnection.addConnectionEventListener(this);
+        final PooledConnectionAndInfo pci = new PooledConnectionAndInfo(pooledConnection, userName, upkey.getPasswordCharArray());
+        pcMap.put(pooledConnection, pci);
 
         return new DefaultPooledObject<>(pci);
     }
@@ -139,10 +139,10 @@ class KeyedCPDSConnectionFactory implements KeyedPooledObjectFactory<UserPassKey
      */
     @Override
     public void destroyObject(final UserPassKey key, final PooledObject<PooledConnectionAndInfo> p) throws Exception {
-        final PooledConnection pc = p.getObject().getPooledConnection();
-        pc.removeConnectionEventListener(this);
-        pcMap.remove(pc);
-        pc.close();
+        final PooledConnection pooledConnection = p.getObject().getPooledConnection();
+        pooledConnection.removeConnectionEventListener(this);
+        pcMap.remove(pooledConnection);
+        pooledConnection.close();
     }
 
     @Override
@@ -340,9 +340,9 @@ class KeyedCPDSConnectionFactory implements KeyedPooledObjectFactory<UserPassKey
 
     private void validateLifetime(final PooledObject<PooledConnectionAndInfo> p) throws Exception {
         if (maxConnLifetimeMillis > 0) {
-            final long lifetime = System.currentTimeMillis() - p.getCreateTime();
-            if (lifetime > maxConnLifetimeMillis) {
-                throw new Exception(Utils.getMessage("connectionFactory.lifetimeExceeded", Long.valueOf(lifetime),
+            final long lifetimeMillis = System.currentTimeMillis() - p.getCreateTime();
+            if (lifetimeMillis > maxConnLifetimeMillis) {
+                throw new Exception(Utils.getMessage("connectionFactory.lifetimeExceeded", Long.valueOf(lifetimeMillis),
                         Long.valueOf(maxConnLifetimeMillis)));
             }
         }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/datasources/PerUserPoolDataSource.java b/java/org/apache/tomcat/dbcp/dbcp2/datasources/PerUserPoolDataSource.java
index a580173..c1dbb85 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/datasources/PerUserPoolDataSource.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/datasources/PerUserPoolDataSource.java
@@ -134,7 +134,7 @@ public class PerUserPoolDataSource extends InstanceKeyDataSource {
 
     @Override
     protected PooledConnectionManager getConnectionManager(final UserPassKey upKey) {
-        return managers.get(getPoolKey(upKey.getUsername()));
+        return managers.get(getPoolKey(upKey.getUserName()));
     }
 
     private ObjectPool<PooledConnectionAndInfo> getCPDSConnectionFactoryPool(final PooledConnectionManager manager) {
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/datasources/PooledConnectionAndInfo.java b/java/org/apache/tomcat/dbcp/dbcp2/datasources/PooledConnectionAndInfo.java
index 046c382..33bb8e5 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/datasources/PooledConnectionAndInfo.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/datasources/PooledConnectionAndInfo.java
@@ -21,7 +21,7 @@ import javax.sql.PooledConnection;
 import org.apache.tomcat.dbcp.dbcp2.Utils;
 
 /**
- * Immutable poolable object holding a PooledConnection along with the user name and password used to create the
+ * Immutable poolable object holding a {@link PooledConnection} along with the user name and password used to create the
  * connection.
  *
  * @since 2.0
@@ -33,6 +33,8 @@ final class PooledConnectionAndInfo {
     private final UserPassKey upKey;
 
     /**
+     * Constructs a new instance.
+     *
      * @since 2.4.0
      */
     PooledConnectionAndInfo(final PooledConnection pc, final String userName, final char[] userPassword) {
@@ -43,6 +45,8 @@ final class PooledConnectionAndInfo {
     }
 
     /**
+     * Constructs a new instance.
+     *
      * @deprecated Since 2.4.0
      */
     @Deprecated
@@ -50,6 +54,11 @@ final class PooledConnectionAndInfo {
         this(pc, userName, Utils.toCharArray(userPassword));
     }
 
+    /**
+     * Gets the pooled connection.
+     *
+     * @return the pooled connection.
+     */
     PooledConnection getPooledConnection() {
         return pooledConnection;
     }
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/datasources/SharedPoolDataSource.java b/java/org/apache/tomcat/dbcp/dbcp2/datasources/SharedPoolDataSource.java
index 2556e4b..a4f56e5 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/datasources/SharedPoolDataSource.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/datasources/SharedPoolDataSource.java
@@ -75,9 +75,6 @@ public class SharedPoolDataSource extends InstanceKeyDataSource {
         InstanceKeyDataSourceFactory.removeInstance(getInstanceKey());
     }
 
-    // -------------------------------------------------------------------
-    // Properties
-
     /**
      * Gets {@link GenericKeyedObjectPool#getMaxTotal()} for this pool.
      *
@@ -119,9 +116,6 @@ public class SharedPoolDataSource extends InstanceKeyDataSource {
         return pool == null ? 0 : pool.getNumIdle();
     }
 
-    // ----------------------------------------------------------------------
-    // Inherited abstract methods
-
     @Override
     protected PooledConnectionAndInfo getPooledConnectionAndInfo(final String userName, final String userPassword)
             throws SQLException {
@@ -154,7 +148,7 @@ public class SharedPoolDataSource extends InstanceKeyDataSource {
     }
 
     /**
-     * Returns a <code>SharedPoolDataSource</code> {@link Reference}.
+     * Creates a new {@link Reference} to a {@link SharedPoolDataSource}.
      */
     @Override
     public Reference getReference() throws NamingException {
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/datasources/UserPassKey.java b/java/org/apache/tomcat/dbcp/dbcp2/datasources/UserPassKey.java
index 9fd0af3..d3b5570 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/datasources/UserPassKey.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/datasources/UserPassKey.java
@@ -20,13 +20,14 @@ import java.io.Serializable;
 import java.util.Objects;
 
 import org.apache.tomcat.dbcp.dbcp2.Utils;
+import org.apache.tomcat.dbcp.pool2.KeyedObjectPool;
 
 /**
  * <p>
- * Holds a user name and password pair. Serves as a poolable object key for the KeyedObjectPool backing a
- * SharedPoolDataSource. Two instances with the same user name are considered equal. This ensures that there will be
- * only one keyed pool for each user in the pool. The password is used (along with the user name) by the
- * KeyedCPDSConnectionFactory when creating new connections.
+ * Holds a user name and password pair. Serves as a poolable object key for the {@link KeyedObjectPool} backing a
+ * {@link SharedPoolDataSource}. Two instances with the same user name are considered equal. This ensures that there
+ * will be only one keyed pool for each user in the pool. The password is used (along with the user name) by the
+ * {@code KeyedCPDSConnectionFactory} when creating new connections.
  * </p>
  *
  * <p>
@@ -83,7 +84,7 @@ class UserPassKey implements Serializable {
      *
      * @return value of password.
      */
-    public String getPassword() {
+    String getPassword() {
         return Utils.toString(userPassword);
     }
 
@@ -92,7 +93,7 @@ class UserPassKey implements Serializable {
      *
      * @return value of password.
      */
-    public char[] getPasswordCharArray() {
+    char[] getPasswordCharArray() {
         return userPassword;
     }
 
@@ -101,7 +102,7 @@ class UserPassKey implements Serializable {
      *
      * @return value of user name.
      */
-    public String getUsername() {
+    String getUserName() {
         return userName;
     }
 
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 1dc44cb..d32e370 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -200,6 +200,10 @@
         Update the internal fork of Apache Commons Pool to 0da5c54
         (2021-02-02, 2.9.1-SNAPSHOT). Refactoring and code clean-up. (markt)
       </add>
+      <add>
+        Update the internal fork of Apache Commons DBCP to c6d5cd9
+        (2021-06-05, 2.9.0-SNAPSHOT). Refactoring and code clean-up. (markt)
+      </add>
     </changelog>
   </subsection>
 </section>

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