Author: markt Date: Mon Dec 4 21:13:36 2017 New Revision: 1817126 URL: http://svn.apache.org/viewvc?rev=1817126&view=rev Log: Align packaged renamed DBCP2 with original. Update the internal fork of Commons DBCP 2 to 8a71764 (2017-10-18)
Modified: tomcat/trunk/MERGE.txt tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.java tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/DelegatingConnection.java tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/DelegatingDatabaseMetaData.java tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/DelegatingResultSet.java tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/DelegatingStatement.java tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PStmtKey.java tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnection.java tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionFactory.java tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingDataSource.java tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PStmtKeyCPDS.java tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSourceFactory.java tomcat/trunk/webapps/docs/changelog.xml Modified: tomcat/trunk/MERGE.txt URL: http://svn.apache.org/viewvc/tomcat/trunk/MERGE.txt?rev=1817126&r1=1817125&r2=1817126&view=diff ============================================================================== --- tomcat/trunk/MERGE.txt (original) +++ tomcat/trunk/MERGE.txt Mon Dec 4 21:13:36 2017 @@ -32,24 +32,12 @@ merges. This file keeps track of these c them up to date. BCEL +---- org.apache.tomcat.util.bcel is copied from: /commons/proper/bcel/trunk/src/main/java/org/apache/bcel -DBCP (inc. Pool2) -org.apache.tomcat.dbcp.dbcp2 is copied from: -/commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2 -and -/commons/proper/dbcp/trunk/src/main/resources/org/apache/commons/dbcp2 - -Pool2 used to be hosted in svn. All changes up to the point where Pool2 was -migrated to git have been merged. - - -FileUpload -This used to be hosted in svn. All changes up to the point where FileUpload was -migrated to git have been merged. - Codec +----- org.apache.tomcat.util.codec is copied from: /commons/proper/codec/trunk/src/main/java/org/apache/commons/codec/ Note: Only classes required for Base64 encoding/decoding. The rest are removed. @@ -65,6 +53,7 @@ The more recently merged SHA1 for the co the patch file has been applied and committed FileUpload +---------- Sub-tree: src/main/java/org/apache/commons/fileupload The SHA1 ID for the most recent commit to be merged to Tomcat is: @@ -73,6 +62,15 @@ The SHA1 ID for the most recent commit t Note: Tomcat's copy of fileupload also includes classes copied manually (rather than svn copied) from Commons IO. +DBCP +---- +DBCP2 +Sub-tree +/commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2 +/commons/proper/dbcp/trunk/src/main/resources/org/apache/commons/dbcp2 +The SHA1 ID for the most recent commit to be merged to Tomcat is: +8a71764a895b234bd1fc76553835ef4c974f22e1 + Pool2 Sub-tree src/main/java/org/apache/commons/pool2 Modified: tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.java?rev=1817126&r1=1817125&r2=1817126&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.java (original) +++ tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.java Mon Dec 4 21:13:36 2017 @@ -106,7 +106,7 @@ public class BasicDataSource implements /** * The default auto-commit state of connections created by this pool. */ - private volatile Boolean defaultAutoCommit = null; + private volatile Boolean defaultAutoCommit; /** * Returns the default auto-commit property. @@ -137,7 +137,7 @@ public class BasicDataSource implements /** * The default read-only state of connections created by this pool. */ - private transient Boolean defaultReadOnly = null; + private transient Boolean defaultReadOnly; /** * Returns the default readOnly property. @@ -198,7 +198,7 @@ public class BasicDataSource implements } - private Integer defaultQueryTimeout = null; + private Integer defaultQueryTimeout; /** * Obtain the default query timeout that will be used for {@link java.sql.Statement Statement}s @@ -225,7 +225,7 @@ public class BasicDataSource implements /** * The default "catalog" of connections created by this pool. */ - private volatile String defaultCatalog = null; + private volatile String defaultCatalog; /** * Returns the default catalog. @@ -284,7 +284,7 @@ public class BasicDataSource implements /** * The instance of the JDBC Driver to use. */ - private Driver driver = null; + private Driver driver; /** * Returns the JDBC Driver that has been configured for use by this pool. @@ -317,7 +317,7 @@ public class BasicDataSource implements /** * The fully qualified Java class name of the JDBC driver to be used. */ - private String driverClassName = null; + private String driverClassName; /** * Returns the JDBC driver class name. @@ -358,7 +358,7 @@ public class BasicDataSource implements * If specified, {@link Class#forName(String, boolean, ClassLoader)} is * used. */ - private ClassLoader driverClassLoader = null; + private ClassLoader driverClassLoader; /** * Returns the class loader specified for loading the JDBC driver. Returns @@ -1008,7 +1008,7 @@ public class BasicDataSource implements * The connection password to be passed to our JDBC driver to establish * a connection. */ - private volatile String password = null; + private volatile String password; /** * Returns the password passed to the JDBC driver to establish connections. @@ -1038,7 +1038,7 @@ public class BasicDataSource implements * The connection URL to be passed to our JDBC driver to establish * a connection. */ - private String url = null; + private String url; /** * Returns the JDBC connection {@link #url} property. @@ -1069,7 +1069,7 @@ public class BasicDataSource implements * The connection username to be passed to our JDBC driver to * establish a connection. */ - private String username = null; + private String username; /** * Returns the JDBC connection {@link #username} property. @@ -1103,7 +1103,7 @@ public class BasicDataSource implements * one row. If not specified, {@link Connection#isValid(int)} will be used * to validate connections. */ - private volatile String validationQuery = null; + private volatile String validationQuery; /** * Returns the validation query used to validate connections before @@ -1315,7 +1315,7 @@ public class BasicDataSource implements this.logExpiredConnections = logExpiredConnections; } - private String jmxName = null; + private String jmxName; /** * @return the JMX name that has been requested for this DataSource. If the @@ -1484,7 +1484,7 @@ public class BasicDataSource implements /** * The object pool that internally manages our connections. */ - private volatile GenericObjectPool<PoolableConnection> connectionPool = null; + private volatile GenericObjectPool<PoolableConnection> connectionPool; protected GenericObjectPool<PoolableConnection> getConnectionPool() { return connectionPool; @@ -1508,7 +1508,7 @@ public class BasicDataSource implements * be acquired <strong>ONLY</strong> by calls to the * <code>createDataSource()</code> method. */ - private volatile DataSource dataSource = null; + private volatile DataSource dataSource; /** * The PrintWriter to which log messages should be directed. @@ -1677,6 +1677,10 @@ public class BasicDataSource implements } abandonedConfig.setRemoveAbandonedOnMaintenance( removeAbandonedOnMaintenance); + final GenericObjectPool<?> gop = this.connectionPool; + if (gop != null) { + gop.setAbandonedConfig(abandonedConfig); + } } /** @@ -1709,6 +1713,10 @@ public class BasicDataSource implements abandonedConfig = new AbandonedConfig(); } abandonedConfig.setRemoveAbandonedOnBorrow(removeAbandonedOnBorrow); + final GenericObjectPool<?> gop = this.connectionPool; + if (gop != null) { + gop.setAbandonedConfig(abandonedConfig); + } } /** @@ -1754,6 +1762,10 @@ public class BasicDataSource implements abandonedConfig = new AbandonedConfig(); } abandonedConfig.setRemoveAbandonedTimeout(removeAbandonedTimeout); + final GenericObjectPool<?> gop = this.connectionPool; + if (gop != null) { + gop.setAbandonedConfig(abandonedConfig); + } } /** @@ -1782,6 +1794,10 @@ public class BasicDataSource implements abandonedConfig = new AbandonedConfig(); } abandonedConfig.setLogAbandoned(logAbandoned); + final GenericObjectPool<?> gop = this.connectionPool; + if (gop != null) { + gop.setAbandonedConfig(abandonedConfig); + } } /** @@ -1807,6 +1823,10 @@ public class BasicDataSource implements abandonedConfig = new AbandonedConfig(); } abandonedConfig.setLogWriter(logWriter); + final GenericObjectPool<?> gop = this.connectionPool; + if (gop != null) { + gop.setAbandonedConfig(abandonedConfig); + } } /** @@ -1840,6 +1860,10 @@ public class BasicDataSource implements abandonedConfig = new AbandonedConfig(); } abandonedConfig.setUseUsageTracking(usageTracking); + final GenericObjectPool<?> gop = this.connectionPool; + if (gop != null) { + gop.setAbandonedConfig(abandonedConfig); + } } // --------------------------------------------------------- Public Methods @@ -2044,7 +2068,7 @@ public class BasicDataSource implements driverConnectionFactory); poolableConnectionFactory.setPoolStatements( poolPreparedStatements); - poolableConnectionFactory.setMaxOpenPrepatedStatements( + poolableConnectionFactory.setMaxOpenPreparedStatements( maxOpenPreparedStatements); success = true; } catch (final SQLException se) { @@ -2204,15 +2228,7 @@ public class BasicDataSource implements final GenericObjectPoolConfig config = new GenericObjectPoolConfig(); updateJmxName(config); config.setJmxEnabled(registeredJmxName != null); // Disable JMX on the underlying pool if the DS is not registered. - GenericObjectPool<PoolableConnection> gop; - if (abandonedConfig != null && - (abandonedConfig.getRemoveAbandonedOnBorrow() || - abandonedConfig.getRemoveAbandonedOnMaintenance())) { - gop = new GenericObjectPool<>(factory, config, abandonedConfig); - } - else { - gop = new GenericObjectPool<>(factory, config); - } + final GenericObjectPool<PoolableConnection> gop = createObjectPool(factory, config, abandonedConfig); gop.setMaxTotal(maxTotal); gop.setMaxIdle(maxIdle); gop.setMinIdle(minIdle); @@ -2232,6 +2248,29 @@ public class BasicDataSource implements } /** + * Creates an object pool used to provide pooling support for {@link Connection JDBC connections}. + * + * @param factory the object factory + * @param poolConfig the object pool configuration + * @param abandonedConfig the abandoned objects configuration + * @return a non-null instance + */ + protected GenericObjectPool<PoolableConnection> createObjectPool( + final PoolableConnectionFactory factory, final GenericObjectPoolConfig poolConfig, + final AbandonedConfig abandonedConfig) { + GenericObjectPool<PoolableConnection> gop; + if (abandonedConfig != null && + (abandonedConfig.getRemoveAbandonedOnBorrow() || + abandonedConfig.getRemoveAbandonedOnMaintenance())) { + gop = new GenericObjectPool<>(factory, poolConfig, abandonedConfig); + } + else { + gop = new GenericObjectPool<>(factory, poolConfig); + } + return gop; + } + + /** * Closes the connection pool, silently swallowing any exception that occurs. */ private void closeConnectionPool() { @@ -2289,7 +2328,7 @@ public class BasicDataSource implements connectionFactory.setDefaultCatalog(defaultCatalog); connectionFactory.setCacheState(cacheState); connectionFactory.setPoolStatements(poolPreparedStatements); - connectionFactory.setMaxOpenPrepatedStatements(maxOpenPreparedStatements); + connectionFactory.setMaxOpenPreparedStatements(maxOpenPreparedStatements); connectionFactory.setMaxConnLifetimeMillis(maxConnLifetimeMillis); connectionFactory.setRollbackOnReturn(getRollbackOnReturn()); connectionFactory.setEnableAutoCommitOnReturn(getEnableAutoCommitOnReturn()); Modified: tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/DelegatingConnection.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/DelegatingConnection.java?rev=1817126&r1=1817125&r2=1817126&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/DelegatingConnection.java (original) +++ tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/DelegatingConnection.java Mon Dec 4 21:13:36 2017 @@ -35,6 +35,7 @@ import java.sql.Savepoint; import java.sql.Statement; import java.sql.Struct; import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; @@ -633,7 +634,9 @@ public class DelegatingConnection<C exte // DBCP-288. Not all the traced objects will be statements final List<AbandonedTrace> traces = getTrace(); if(traces != null && traces.size() > 0) { - for (AbandonedTrace trace : traces) { + final Iterator<AbandonedTrace> traceIter = traces.iterator(); + while (traceIter.hasNext()) { + final Object trace = traceIter.next(); if (trace instanceof Statement) { ((Statement) trace).close(); } else if (trace instanceof ResultSet) { Modified: tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/DelegatingDatabaseMetaData.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/DelegatingDatabaseMetaData.java?rev=1817126&r1=1817125&r2=1817126&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/DelegatingDatabaseMetaData.java (original) +++ tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/DelegatingDatabaseMetaData.java Mon Dec 4 21:13:36 2017 @@ -59,7 +59,7 @@ public class DelegatingDatabaseMetaData * Hence this method will return the first * delegate that is not a {@code DelegatingResultSet}, * or {@code null} when no non-{@code DelegatingResultSet} - * delegate can be found by transversing this chain. + * delegate can be found by traversing this chain. * <p> * This method is useful when you may have nested * {@code DelegatingResultSet}s, and you want to make Modified: tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/DelegatingResultSet.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/DelegatingResultSet.java?rev=1817126&r1=1817125&r2=1817126&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/DelegatingResultSet.java (original) +++ tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/DelegatingResultSet.java Mon Dec 4 21:13:36 2017 @@ -128,7 +128,7 @@ public final class DelegatingResultSet e * Hence this method will return the first * delegate that is not a {@code DelegatingResultSet}, * or {@code null} when no non-{@code DelegatingResultSet} - * delegate can be found by transversing this chain. + * delegate can be found by traversing this chain. * <p> * This method is useful when you may have nested * {@code DelegatingResultSet}s, and you want to make Modified: tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/DelegatingStatement.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/DelegatingStatement.java?rev=1817126&r1=1817125&r2=1817126&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/DelegatingStatement.java (original) +++ tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/DelegatingStatement.java Mon Dec 4 21:13:36 2017 @@ -81,7 +81,7 @@ public class DelegatingStatement extends * Hence this method will return the first * delegate that is not a {@code DelegatingStatement} * or {@code null} when no non-{@code DelegatingStatement} - * delegate can be found by transversing this chain. + * delegate can be found by traversing this chain. * <p> * This method is useful when you may have nested * {@code DelegatingStatement}s, and you want to make Modified: tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PStmtKey.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PStmtKey.java?rev=1817126&r1=1817125&r2=1817126&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PStmtKey.java (original) +++ tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PStmtKey.java Mon Dec 4 21:13:36 2017 @@ -16,6 +16,12 @@ */ package org.apache.tomcat.dbcp.dbcp2; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Arrays; + import org.apache.tomcat.dbcp.dbcp2.PoolingConnection.StatementType; /** @@ -33,22 +39,51 @@ public class PStmtKey { /** Result set concurrency */ private final Integer _resultSetConcurrency; + /** Result set holdability */ + private final Integer _resultSetHoldability; + /** Database catalog */ private final String _catalog; /** Auto generated keys */ private final Integer _autoGeneratedKeys; + /** column indexes */ + private final int[] _columnIndexes; + + /** column names */ + private final String[] _columnNames; + /** Statement type */ private final StatementType _stmtType; + /** Statement builder */ + private StatementBuilder builder; public PStmtKey(final String sql) { - this(sql, null, StatementType.PREPARED_STATEMENT, null); + this(sql, null, StatementType.PREPARED_STATEMENT); } public PStmtKey(final String sql, final String catalog) { - this(sql, catalog, StatementType.PREPARED_STATEMENT, null); + this(sql, catalog, StatementType.PREPARED_STATEMENT); + } + + public PStmtKey(final String sql, final String catalog, final StatementType stmtType) { + _sql = sql; + _catalog = catalog; + _stmtType = stmtType; + _autoGeneratedKeys = null; + _columnIndexes = null; + _columnNames = null; + _resultSetType = null; + _resultSetConcurrency = null; + _resultSetHoldability = null; + // create builder + if (stmtType == StatementType.PREPARED_STATEMENT) { + builder = new PreparedStatementSQL(); + } else if (stmtType == StatementType.CALLABLE_STATEMENT) { + builder = new PreparedCallSQL(); + } } public PStmtKey(final String sql, final String catalog, final int autoGeneratedKeys) { @@ -60,8 +95,45 @@ public class PStmtKey { _catalog = catalog; _stmtType = stmtType; _autoGeneratedKeys = autoGeneratedKeys; + _columnIndexes = null; + _columnNames = null; + _resultSetType = null; + _resultSetConcurrency = null; + _resultSetHoldability = null; + // create builder + if (stmtType == StatementType.PREPARED_STATEMENT) { + builder = new PreparedStatementWithAutoGeneratedKeys(); + } else if (stmtType == StatementType.CALLABLE_STATEMENT) { + builder = new PreparedCallSQL(); + } + } + + public PStmtKey(final String sql, final String catalog, final int[] columnIndexes) { + _sql = sql; + _catalog = catalog; + _stmtType = StatementType.PREPARED_STATEMENT; + _autoGeneratedKeys = null; + _columnIndexes = columnIndexes; + _columnNames = null; _resultSetType = null; _resultSetConcurrency = null; + _resultSetHoldability = null; + // create builder + builder = new PreparedStatementWithColumnIndexes(); + } + + public PStmtKey(final String sql, final String catalog, final String[] columnNames) { + _sql = sql; + _catalog = catalog; + _stmtType = StatementType.PREPARED_STATEMENT; + _autoGeneratedKeys = null; + _columnIndexes = null; + _columnNames = columnNames; + _resultSetType = null; + _resultSetConcurrency = null; + _resultSetHoldability = null; + // create builder + builder = new PreparedStatementWithColumnNames(); } public PStmtKey(final String sql, final int resultSetType, final int resultSetConcurrency) { @@ -77,8 +149,41 @@ public class PStmtKey { _catalog = catalog; _resultSetType = Integer.valueOf(resultSetType); _resultSetConcurrency = Integer.valueOf(resultSetConcurrency); + _resultSetHoldability = null; _stmtType = stmtType; _autoGeneratedKeys = null; + _columnIndexes = null; + _columnNames = null; + // create builder + if (stmtType == StatementType.PREPARED_STATEMENT) { + builder = new PreparedStatementWithResultSetConcurrency(); + } else if (stmtType == StatementType.CALLABLE_STATEMENT) { + builder = new PreparedCallWithResultSetConcurrency(); + } + } + + public PStmtKey(final String sql, final String catalog, final int resultSetType, final int resultSetConcurrency, + final int resultSetHoldability) { + this(sql, catalog, resultSetType, resultSetConcurrency, resultSetHoldability, StatementType.PREPARED_STATEMENT); + } + + public PStmtKey(final String sql, final String catalog, final int resultSetType, final int resultSetConcurrency, + final int resultSetHoldability, final StatementType stmtType) { + _sql = sql; + _catalog = catalog; + _resultSetType = Integer.valueOf(resultSetType); + _resultSetConcurrency = Integer.valueOf(resultSetConcurrency); + _resultSetHoldability = Integer.valueOf(resultSetHoldability); + _stmtType = stmtType; + _autoGeneratedKeys = null; + _columnIndexes = null; + _columnNames = null; + // create builder + if (stmtType == StatementType.PREPARED_STATEMENT) { + builder = new PreparedStatementWithResultSetHoldability(); + } else if (stmtType == StatementType.CALLABLE_STATEMENT) { + builder = new PreparedCallWithResultSetHoldability(); + } } @@ -94,10 +199,22 @@ public class PStmtKey { return _resultSetConcurrency; } + public Integer getResultSetHoldability() { + return _resultSetHoldability; + } + public Integer getAutoGeneratedKeys() { return _autoGeneratedKeys; } + public int[] getColumnIndexes() { + return _columnIndexes; + } + + public String[] getColumnNames() { + return _columnNames; + } + public String getCatalog() { return _catalog; } @@ -139,6 +256,13 @@ public class PStmtKey { } else if (!_resultSetType.equals(other._resultSetType)) { return false; } + if (_resultSetHoldability == null) { + if (other._resultSetHoldability != null) { + return false; + } + } else if (!_resultSetHoldability.equals(other._resultSetHoldability)) { + return false; + } if (_autoGeneratedKeys == null) { if (other._autoGeneratedKeys != null) { return false; @@ -146,6 +270,12 @@ public class PStmtKey { } else if (!_autoGeneratedKeys.equals(other._autoGeneratedKeys)) { return false; } + if (!Arrays.equals(_columnIndexes, other._columnIndexes)) { + return false; + } + if (!Arrays.equals(_columnNames, other._columnNames)) { + return false; + } if (_sql == null) { if (other._sql != null) { return false; @@ -166,8 +296,11 @@ public class PStmtKey { result = prime * result + (_catalog == null ? 0 : _catalog.hashCode()); result = prime * result + (_resultSetConcurrency == null ? 0 : _resultSetConcurrency.hashCode()); result = prime * result + (_resultSetType == null ? 0 : _resultSetType.hashCode()); + result = prime * result + (_resultSetHoldability == null ? 0 : _resultSetHoldability.hashCode()); result = prime * result + (_sql == null ? 0 : _sql.hashCode()); result = prime * result + (_autoGeneratedKeys == null ? 0 : _autoGeneratedKeys.hashCode()); + result = prime * result + Arrays.hashCode(_columnIndexes); + result = prime * result + Arrays.hashCode(_columnNames); result = prime * result + _stmtType.hashCode(); return result; } @@ -183,10 +316,138 @@ public class PStmtKey { buf.append(_resultSetType); buf.append(", resultSetConcurrency="); buf.append(_resultSetConcurrency); + buf.append(", resultSetHoldability="); + buf.append(_resultSetHoldability); buf.append(", autoGeneratedKeys="); buf.append(_autoGeneratedKeys); - buf.append(", statmentType="); + buf.append(", columnIndexes="); + buf.append(Arrays.toString(_columnIndexes)); + buf.append(", columnNames="); + buf.append(Arrays.toString(_columnNames)); + buf.append(", statementType="); buf.append(_stmtType); return buf.toString(); } + + public Statement createStatement(final Connection connection) throws SQLException { + if (builder == null) { + throw new IllegalStateException("Prepared statement key is invalid."); + } + return builder.createStatement(connection); + } + + /** + * Interface for Prepared or Callable Statement + */ + private interface StatementBuilder { + public Statement createStatement(Connection connection) throws SQLException; + } + + /** + * Builder for prepareStatement(String sql) + */ + private class PreparedStatementSQL implements StatementBuilder { + @Override + public Statement createStatement(final Connection connection) throws SQLException { + final PreparedStatement statement = connection.prepareStatement(_sql); + return statement; + } + } + + /** + * Builder for prepareStatement(String sql, int autoGeneratedKeys) + */ + private class PreparedStatementWithAutoGeneratedKeys implements StatementBuilder { + @Override + public Statement createStatement(final Connection connection) throws SQLException { + final PreparedStatement statement = connection.prepareStatement( + _sql, _autoGeneratedKeys.intValue()); + return statement; + } + } + + /** + * Builder for prepareStatement(String sql, int[] columnIndexes) + */ + private class PreparedStatementWithColumnIndexes implements StatementBuilder { + @Override + public Statement createStatement(final Connection connection) throws SQLException { + final PreparedStatement statement = connection.prepareStatement( + _sql, _columnIndexes); + return statement; + } + } + + /** + * Builder for prepareStatement(String sql, int resultSetType, int resultSetConcurrency) + */ + private class PreparedStatementWithResultSetConcurrency implements StatementBuilder { + @Override + public Statement createStatement(final Connection connection) throws SQLException { + final PreparedStatement statement = connection.prepareStatement( + _sql, _resultSetType.intValue(), _resultSetConcurrency.intValue()); + return statement; + } + } + + /** + * Builder for prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) + */ + private class PreparedStatementWithResultSetHoldability implements StatementBuilder { + @Override + public Statement createStatement(final Connection connection) throws SQLException { + final PreparedStatement statement = connection.prepareStatement( + _sql, _resultSetType.intValue(), _resultSetConcurrency.intValue(), + _resultSetHoldability.intValue()); + return statement; + } + } + + /** + * Builder for prepareStatement(String sql, String[] columnNames) + */ + private class PreparedStatementWithColumnNames implements StatementBuilder { + @Override + public Statement createStatement(final Connection connection) throws SQLException { + final PreparedStatement statement = connection.prepareStatement( + _sql, _columnNames); + return statement; + } + } + + /** + * Builder for prepareCall(String sql) + */ + private class PreparedCallSQL implements StatementBuilder { + @Override + public Statement createStatement(final Connection connection) throws SQLException { + final PreparedStatement statement = connection.prepareCall(_sql); + return statement; + } + } + + /** + * Builder for prepareCall(String sql, int resultSetType, int resultSetConcurrency) + */ + private class PreparedCallWithResultSetConcurrency implements StatementBuilder { + @Override + public Statement createStatement(final Connection connection) throws SQLException { + final PreparedStatement statement = connection.prepareCall( + _sql, _resultSetType.intValue(), _resultSetConcurrency.intValue()); + return statement; + } + } + + /** + * Builder for prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) + */ + private class PreparedCallWithResultSetHoldability implements StatementBuilder { + @Override + public Statement createStatement(final Connection connection) throws SQLException { + final PreparedStatement statement = connection.prepareCall( + _sql, _resultSetType.intValue(), _resultSetConcurrency.intValue(), + _resultSetHoldability.intValue()); + return statement; + } + } } Modified: tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnection.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnection.java?rev=1817126&r1=1817125&r2=1817126&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnection.java (original) +++ tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnection.java Mon Dec 4 21:13:36 2017 @@ -164,9 +164,9 @@ public class PoolableConnection extends return; } - boolean isUnderlyingConectionClosed; + boolean isUnderlyingConnectionClosed; try { - isUnderlyingConectionClosed = getDelegateInternal().isClosed(); + isUnderlyingConnectionClosed = getDelegateInternal().isClosed(); } catch (final SQLException e) { try { _pool.invalidateObject(this); @@ -186,7 +186,7 @@ public class PoolableConnection extends * may have been borrowed by another thread. Therefore, the close flag * is set in passivate(). */ - if (isUnderlyingConectionClosed) { + if (isUnderlyingConnectionClosed) { // Abnormal close: underlying connection closed unexpectedly, so we // must destroy this proxy try { @@ -325,7 +325,8 @@ public class PoolableConnection extends fatalException = _disconnectionSqlCodes == null ? sqlState.startsWith(Utils.DISCONNECTION_SQL_CODE_PREFIX) || Utils.DISCONNECTION_SQL_CODES.contains(sqlState) : _disconnectionSqlCodes.contains(sqlState); if (!fatalException) { - if (e.getNextException() != null) { + final SQLException nextException = e.getNextException(); + if (nextException != null && nextException != e) { fatalException = isDisconnectionSqlException(e.getNextException()); } } Modified: tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionFactory.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionFactory.java?rev=1817126&r1=1817125&r2=1817126&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionFactory.java (original) +++ tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionFactory.java Mon Dec 4 21:13:36 2017 @@ -158,7 +158,12 @@ public class PoolableConnectionFactory this.poolStatements = poolStatements; } + @Deprecated // Due to typo in method name. public void setMaxOpenPrepatedStatements(final int maxOpenPreparedStatements) { + setMaxOpenPreparedStatements(maxOpenPreparedStatements); + } + + public void setMaxOpenPreparedStatements(final int maxOpenPreparedStatements) { this.maxOpenPreparedStatements = maxOpenPreparedStatements; } Modified: tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java?rev=1817126&r1=1817125&r2=1817126&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java (original) +++ tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java Mon Dec 4 21:13:36 2017 @@ -203,26 +203,104 @@ public class PoolingConnection extends D } } + /** + * Create or obtain a {@link PreparedStatement} from the pool. + * @param sql the sql string used to define the PreparedStatement + * @param resultSetType result set type + * @param resultSetConcurrency result set concurrency + * @param resultSetHoldability result set holdability + * @return a {@link PoolablePreparedStatement} + */ + @Override + public PreparedStatement prepareStatement(final String sql, final int resultSetType, + final int resultSetConcurrency, final int resultSetHoldability) throws SQLException { + if (null == _pstmtPool) { + throw new SQLException( + "Statement pool is null - closed or invalid PoolingConnection."); + } + try { + return _pstmtPool.borrowObject(createKey(sql, resultSetType, resultSetConcurrency, resultSetHoldability)); + } catch(final NoSuchElementException e) { + throw new SQLException("MaxOpenPreparedStatements limit reached", e); + } catch(final RuntimeException e) { + throw e; + } catch(final Exception e) { + throw new SQLException("Borrow prepareStatement from pool failed", e); + } + } -// TODO: possible enhancement, cache these preparedStatements as well + /** + * Create or obtain a {@link PreparedStatement} from the pool. + * @param sql the sql string used to define the PreparedStatement + * @param columnIndexes column indexes + * @return a {@link PoolablePreparedStatement} + */ + @Override + public PreparedStatement prepareStatement(final String sql, final int columnIndexes[]) + throws SQLException { + if (null == _pstmtPool) { + throw new SQLException( + "Statement pool is null - closed or invalid PoolingConnection."); + } + try { + return _pstmtPool.borrowObject(createKey(sql, columnIndexes)); + } catch(final NoSuchElementException e) { + throw new SQLException("MaxOpenPreparedStatements limit reached", e); + } catch(final RuntimeException e) { + throw e; + } catch(final Exception e) { + throw new SQLException("Borrow prepareStatement from pool failed", e); + } + } -// public PreparedStatement prepareStatement(String sql, int resultSetType, -// int resultSetConcurrency, -// int resultSetHoldability) -// throws SQLException { -// return super.prepareStatement( -// sql, resultSetType, resultSetConcurrency, resultSetHoldability); -// } -// -// public PreparedStatement prepareStatement(String sql, int columnIndexes[]) -// throws SQLException { -// return super.prepareStatement(sql, columnIndexes); -// } -// -// public PreparedStatement prepareStatement(String sql, String columnNames[]) -// throws SQLException { -// return super.prepareStatement(sql, columnNames); -// } + /** + * Create or obtain a {@link PreparedStatement} from the pool. + * @param sql the sql string used to define the PreparedStatement + * @param columnNames column names + * @return a {@link PoolablePreparedStatement} + */ + @Override + public PreparedStatement prepareStatement(final String sql, final String columnNames[]) + throws SQLException { + if (null == _pstmtPool) { + throw new SQLException( + "Statement pool is null - closed or invalid PoolingConnection."); + } + try { + return _pstmtPool.borrowObject(createKey(sql, columnNames)); + } catch(final NoSuchElementException e) { + throw new SQLException("MaxOpenPreparedStatements limit reached", e); + } catch(final RuntimeException e) { + throw e; + } catch(final Exception e) { + throw new SQLException("Borrow prepareStatement from pool failed", e); + } + } + + /** + * Create or obtain a {@link CallableStatement} from the pool. + * @param sql the sql string used to define the CallableStatement + * @param resultSetType result set type + * @param resultSetConcurrency result set concurrency + * @param resultSetHoldability result set holdability + * @return a {@link PoolableCallableStatement} + * @throws SQLException if a {@link CallableStatement} cannot be obtained + * from the pool + */ + @Override + public CallableStatement prepareCall(final String sql, final int resultSetType, + final int resultSetConcurrency, final int resultSetHoldability) throws SQLException { + try { + return (CallableStatement) _pstmtPool.borrowObject(createKey(sql, resultSetType, + resultSetConcurrency, resultSetHoldability, StatementType.CALLABLE_STATEMENT)); + } catch (final NoSuchElementException e) { + throw new SQLException("MaxOpenCallableStatements limit reached", e); + } catch (final RuntimeException e) { + throw e; + } catch (final Exception e) { + throw new SQLException("Borrow callableStatement from pool failed", e); + } + } protected PStmtKey createKey(final String sql, final int autoGeneratedKeys) { String catalog = null; @@ -301,6 +379,77 @@ public class PoolingConnection extends D } /** + * Create a PStmtKey for the given arguments. + * @param sql the sql string used to define the statement + * @param resultSetType result set type + * @param resultSetConcurrency result set concurrency + * @param resultSetHoldability result set holdability + * @return a newly created key for the given arguments + */ + protected PStmtKey createKey(final String sql, final int resultSetType, final int resultSetConcurrency, + final int resultSetHoldability) { + String catalog = null; + try { + catalog = getCatalog(); + } catch (final SQLException e) { + // Ignored + } + return new PStmtKey(normalizeSQL(sql), catalog, resultSetType, resultSetConcurrency, resultSetHoldability); + } + + /** + * Create a PStmtKey for the given arguments. + * @param sql the sql string used to define the statement + * @param resultSetType result set type + * @param resultSetConcurrency result set concurrency + * @param resultSetHoldability result set holdability + * @param stmtType statement type + * @return a newly created key for the given arguments + */ + protected PStmtKey createKey(final String sql, final int resultSetType, final int resultSetConcurrency, + final int resultSetHoldability, final StatementType stmtType) { + String catalog = null; + try { + catalog = getCatalog(); + } catch (final SQLException e) { + // Ignored + } + return new PStmtKey(normalizeSQL(sql), catalog, resultSetType, resultSetConcurrency, resultSetHoldability, stmtType); + } + + /** + * Create a PStmtKey for the given arguments. + * @param sql the sql string used to define the statement + * @param columnIndexes column indexes + * @return a newly created key for the given arguments + */ + protected PStmtKey createKey(final String sql, final int columnIndexes[]) { + String catalog = null; + try { + catalog = getCatalog(); + } catch (final SQLException e) { + // Ignored + } + return new PStmtKey(normalizeSQL(sql), catalog, columnIndexes); + } + + /** + * Create a PStmtKey for the given arguments. + * @param sql the sql string used to define the statement + * @param columnNames column names + * @return a newly created key for the given arguments + */ + protected PStmtKey createKey(final String sql, final String columnNames[]) { + String catalog = null; + try { + catalog = getCatalog(); + } catch (final SQLException e) { + // Ignored + } + return new PStmtKey(normalizeSQL(sql), catalog, columnNames); + } + + /** * Normalize the given SQL statement, producing a * canonical form that is semantically equivalent to the original. * @param sql The SQL statement @@ -327,34 +476,16 @@ public class PoolingConnection extends D if(null == key) { throw new IllegalArgumentException("Prepared statement key is null or invalid."); } - if (null == key.getResultSetType() && null == key.getResultSetConcurrency() && null == key.getAutoGeneratedKeys()) { - if (key.getStmtType() == StatementType.PREPARED_STATEMENT ) { - @SuppressWarnings({"rawtypes", "unchecked"}) // Unable to find way to avoid this - final - PoolablePreparedStatement pps = new PoolablePreparedStatement( - getDelegate().prepareStatement(key.getSql()), key, _pstmtPool, this); - return new DefaultPooledObject<>(pps); - } - return new DefaultPooledObject<>( - new PoolableCallableStatement(getDelegate().prepareCall( key.getSql()), key, _pstmtPool, this)); - } else if (null == key.getResultSetType() && null == key.getResultSetConcurrency()){ + if (key.getStmtType() == StatementType.PREPARED_STATEMENT ) { + final PreparedStatement statement = (PreparedStatement) key.createStatement(getDelegate()); @SuppressWarnings({"rawtypes", "unchecked"}) // Unable to find way to avoid this final - PoolablePreparedStatement pps = new PoolablePreparedStatement( - getDelegate().prepareStatement(key.getSql(), key.getAutoGeneratedKeys().intValue()), key, _pstmtPool, this); + PoolablePreparedStatement pps = new PoolablePreparedStatement(statement, key, _pstmtPool, this); return new DefaultPooledObject<>(pps); - } else { // Both _resultSetType and _resultSetConcurrency are non-null here (both or neither are set by constructors) - if(key.getStmtType() == StatementType.PREPARED_STATEMENT) { - @SuppressWarnings({"rawtypes", "unchecked"}) // Unable to find way to avoid this - final - PoolablePreparedStatement pps = new PoolablePreparedStatement(getDelegate().prepareStatement( - key.getSql(), key.getResultSetType().intValue(),key.getResultSetConcurrency().intValue()), key, _pstmtPool, this); - return new DefaultPooledObject<>(pps); - } - return new DefaultPooledObject<>( - new PoolableCallableStatement( getDelegate().prepareCall( - key.getSql(),key.getResultSetType().intValue(), key.getResultSetConcurrency().intValue()), key, _pstmtPool, this)); } + final CallableStatement statement = (CallableStatement) key.createStatement(getDelegate()); + final PoolableCallableStatement pcs = new PoolableCallableStatement(statement, key, _pstmtPool, this); + return new DefaultPooledObject<>(pcs); } /** @@ -430,7 +561,7 @@ public class PoolingConnection extends D * The possible statement types. * @since 2.0 */ - protected enum StatementType { + protected static enum StatementType { CALLABLE_STATEMENT, PREPARED_STATEMENT } Modified: tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingDataSource.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingDataSource.java?rev=1817126&r1=1817125&r2=1817126&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingDataSource.java (original) +++ tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/PoolingDataSource.java Mon Dec 4 21:13:36 2017 @@ -142,6 +142,10 @@ public class PoolingDataSource<C extends throw new SQLException("Cannot get a connection, pool error " + e.getMessage(), e); } catch(final RuntimeException e) { throw e; + } catch(final InterruptedException e) { + // Reset the interrupt status so it is visible to callers + Thread.currentThread().interrupt(); + throw new SQLException("Cannot get a connection, general error", e); } catch(final Exception e) { throw new SQLException("Cannot get a connection, general error", e); } Modified: tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java?rev=1817126&r1=1817125&r2=1817126&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java (original) +++ tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java Mon Dec 4 21:13:36 2017 @@ -70,7 +70,7 @@ import org.apache.tomcat.dbcp.pool2.impl * * <p> * The DriverAdapterCPDS also provides <code>PreparedStatement</code> pooling - * which is not generally available in jbdc2 + * which is not generally available in jdbc2 * <code>ConnectionPoolDataSource</code> implementation, but is * addressed within the jdbc3 specification. The <code>PreparedStatement</code> * pool in DriverAdapterCPDS has been in the dbcp package for some time, but Modified: tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PStmtKeyCPDS.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PStmtKeyCPDS.java?rev=1817126&r1=1817125&r2=1817126&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PStmtKeyCPDS.java (original) +++ tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PStmtKeyCPDS.java Mon Dec 4 21:13:36 2017 @@ -124,7 +124,7 @@ public class PStmtKeyCPDS extends PStmtK buf.append(getResultSetType()); buf.append(", resultSetConcurrency="); buf.append(getResultSetConcurrency()); - buf.append(", statmentType="); + buf.append(", statementType="); buf.append(getStmtType()); buf.append(", resultSetHoldability="); buf.append(_resultSetHoldability); Modified: tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSourceFactory.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSourceFactory.java?rev=1817126&r1=1817125&r2=1817126&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSourceFactory.java (original) +++ tomcat/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSourceFactory.java Mon Dec 4 21:13:36 2017 @@ -20,6 +20,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.util.Hashtable; +import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; @@ -44,7 +45,9 @@ abstract class InstanceKeyDataSourceFact static synchronized String registerNewInstance(final InstanceKeyDataSource ds) { int max = 0; - for (String s : instanceMap.keySet()) { + final Iterator<String> i = instanceMap.keySet().iterator(); + while (i.hasNext()) { + final String s = i.next(); if (s != null) { try { max = Math.max(max, Integer.parseInt(s)); @@ -72,8 +75,10 @@ abstract class InstanceKeyDataSourceFact */ public static void closeAll() throws Exception { //Get iterator to loop over all instances of this datasource. - for (Entry<String, InstanceKeyDataSource> stringInstanceKeyDataSourceEntry : instanceMap.entrySet()) { - stringInstanceKeyDataSourceEntry.getValue().close(); + final Iterator<Entry<String,InstanceKeyDataSource>> instanceIterator = + instanceMap.entrySet().iterator(); + while (instanceIterator.hasNext()) { + instanceIterator.next().getValue().close(); } instanceMap.clear(); } Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1817126&r1=1817125&r2=1817126&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Mon Dec 4 21:13:36 2017 @@ -82,6 +82,10 @@ <update> Update the internal fork of Commons Pool 2 to 2.4.3. (markt) </update> + <update> + Update the internal fork of Commons DBCP 2 to 8a71764 (2017-10-18) to + pick up some bug fixes and enhancements. (markt) + </update> </changelog> </subsection> </section> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org