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