-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Mark,

On 8/26/20 11:19, ma...@apache.org wrote:
> This is an automated email from the ASF dual-hosted git
> repository.
>
> markt pushed a commit to branch master in repository
> https://gitbox.apache.org/repos/asf/tomcat.git
>
> commit f1c4210470a268ec6830a95ab219f418a7e775fb Author: Mark Thomas
> <ma...@apache.org> AuthorDate: Wed Aug 26 16:15:50 2020 +0100
>
> Update Commons DBCP to latest

It looks like, among other things, this includes the fix for
https://issues.apache.org/jira/browse/DBCP-559

If so: hooray!

Can you confirm?

Thanks,
- -chris

> --- MERGE.txt                                          |   2 +-
> .../apache/tomcat/dbcp/dbcp2/BasicDataSource.java  | 187
> +++++++++---------
> .../tomcat/dbcp/dbcp2/BasicDataSourceFactory.java  |  11 +-
> .../tomcat/dbcp/dbcp2/BasicDataSourceMXBean.java   |  29 +++
> .../tomcat/dbcp/dbcp2/DelegatingConnection.java    |   4 +-
> .../tomcat/dbcp/dbcp2/PoolableConnection.java      |   3 +
> .../dbcp/dbcp2/PoolableConnectionFactory.java      |  14 ++
> .../tomcat/dbcp/dbcp2/PoolingConnection.java       | 220
> +++++++++++----------
> .../dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java  |  28 +--
> .../dbcp2/datasources/CPDSConnectionFactory.java   |   3 +-
> .../dbcp2/datasources/InstanceKeyDataSource.java   |   8 +-
> .../dbcp/dbcp2/datasources/package-info.java       |   2 +-
> .../dbcp/dbcp2/managed/BasicManagedDataSource.java |   3 +-
> .../dbcp2/managed/LocalXAConnectionFactory.java    |  21 +-
> webapps/docs/changelog.xml                         |   4 + 15 files
> changed, 323 insertions(+), 216 deletions(-)
>
> diff --git a/MERGE.txt b/MERGE.txt index 79fc82e..b8c152d 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:
> -a363906bf7a039f79c07fa3c68b082a69ae035d7 (2019-12-06)
> +6d232e547d5725e419832fc514fc0348aa897e7c (2020-08-11) diff --git
> a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.java
> b/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.java index
> 0293e9a..31faa61 100644 ---
> a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.java +++
> b/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.java @@ -63,17
> +63,6 @@ import
> org.apache.tomcat.dbcp.pool2.impl.GenericObjectPoolConfig; */
> public class BasicDataSource implements DataSource,
> BasicDataSourceMXBean, MBeanRegistration, AutoCloseable {
>
> -    /** -     * @since 2.0 -     */ -    private class
> PaGetConnection implements PrivilegedExceptionAction<Connection> {
> - -        @Override -        public Connection run() throws
> SQLException { -            return
> createDataSource().getConnection(); -        } -    } - private
> static final Log log = LogFactory.getLog(BasicDataSource.class);
>
> static { @@ -220,6 +209,8 @@ public class BasicDataSource
> implements DataSource, BasicDataSourceMXBean, MBean */ private
> boolean poolPreparedStatements = false;
>
> +    private boolean clearStatementPoolOnReturn = false; + /** *
> <p> * The maximum number of open statements that can be allocated
> from the statement pool at the same time, or negative @@ -402,7
> +393,7 @@ public class BasicDataSource implements DataSource,
> BasicDataSourceMXBean, MBean * </p> * <p> * Attempts to acquire
> connections using {@link #getConnection()} after this method has
> been invoked result in -     * SQLExceptions. +     *
> SQLExceptions.  To reopen a datasource that has been closed using
> this method, use {@link #start()}. * </p> * <p> * This method is
> idempotent - i.e., closing an already closed BasicDataSource has no
> effect and does not generate @@ -448,7 +439,7 @@ public class
> BasicDataSource implements DataSource, BasicDataSourceMXBean,
> MBean }
>
> /** -     * Creates a JDBC connection factory for this datasource.
> The JDBC driver is loaded using the following algorithm: +     *
> Creates a JDBC connection factory for this data source. The JDBC
> driver is loaded using the following algorithm: * <ol> * <li>If a
> Driver instance has been specified via {@link #setDriver(Driver)}
> use it</li> * <li>If no Driver instance was specified and {@link
> #driverClassName} is specified that class is loaded using the @@
> -471,6 +462,7 @@ public class BasicDataSource implements
> DataSource, BasicDataSourceMXBean, MBean return
> ConnectionFactoryFactory.createConnectionFactory(this,
> DriverFactory.createDriver(this)); }
>
> + /** * Creates a connection pool for this datasource. This method
> only exists so subclasses can replace the * implementation class.
> @@ -530,7 +522,6 @@ public class BasicDataSource implements
> DataSource, BasicDataSourceMXBean, MBean if (dataSource != null) {
> return dataSource; } - jmxRegister();
>
> // create factory which returns raw physical connections @@ -544,10
> +535,8 @@ public class BasicDataSource implements DataSource,
> BasicDataSourceMXBean, MBean
> poolableConnectionFactory.setPoolStatements(poolPreparedStatements);
>
>
poolableConnectionFactory.setMaxOpenPreparedStatements(maxOpenPreparedSt
atements);
> success = true; -            } catch (final SQLException se) { +
> } catch (final SQLException | RuntimeException se) { throw se; -
> } catch (final RuntimeException rte) { -                throw rte;
> } catch (final Exception ex) { throw new SQLException("Error
> creating connection factory", ex); } @@ -564,10 +553,8 @@ public
> class BasicDataSource implements DataSource, BasicDataSourceMXBean,
> MBean newDataSource = createDataSourceInstance();
> newDataSource.setLogWriter(logWriter); success = true; -
> } catch (final SQLException se) { +            } catch (final
> SQLException | RuntimeException se) { throw se; -            }
> catch (final RuntimeException rte) { -                throw rte; }
> catch (final Exception ex) { throw new SQLException("Error creating
> datasource", ex); } finally { @@ -654,6 +641,7 @@ public class
> BasicDataSource implements DataSource, BasicDataSourceMXBean,
> MBean connectionFactory.setDefaultSchema(defaultSchema);
> connectionFactory.setCacheState(cacheState);
> connectionFactory.setPoolStatements(poolPreparedStatements); +
> connectionFactory.setClearStatementPoolOnReturn(clearStatementPoolOnRe
turn);
>
>
connectionFactory.setMaxOpenPreparedStatements(maxOpenPreparedStatements
);
> connectionFactory.setMaxConnLifetimeMillis(maxConnLifetimeMillis);
> connectionFactory.setRollbackOnReturn(getRollbackOnReturn()); @@
> -687,10 +675,7 @@ public class BasicDataSource implements
> DataSource, BasicDataSourceMXBean, MBean * @return The print writer
> used by this configuration to log information on abandoned
> objects. */ public PrintWriter getAbandonedLogWriter() { -
> if (abandonedConfig != null) { -            return
> abandonedConfig.getLogWriter(); -        } -        return null; +
> return abandonedConfig == null ? null :
> abandonedConfig.getLogWriter(); }
>
> /** @@ -702,10 +687,7 @@ public class BasicDataSource implements
> DataSource, BasicDataSourceMXBean, MBean */ @Override public
> boolean getAbandonedUsageTracking() { -        if (abandonedConfig
> != null) { -            return
> abandonedConfig.getUseUsageTracking(); -        } -        return
> false; +        return abandonedConfig == null ? false :
> abandonedConfig.getUseUsageTracking(); }
>
> /** @@ -738,7 +720,7 @@ public class BasicDataSource implements
> DataSource, BasicDataSourceMXBean, MBean @Override public
> Connection getConnection() throws SQLException { if
> (Utils.IS_SECURITY_ENABLED) { -            final
> PrivilegedExceptionAction<Connection> action = new
> PaGetConnection(); +            final
> PrivilegedExceptionAction<Connection> action = () ->
> createDataSource().getConnection(); try { return
> AccessController.doPrivileged(action); } catch (final
> PrivilegedActionException e) { @@ -790,10 +772,7 @@ public class
> BasicDataSource implements DataSource, BasicDataSourceMXBean,
> MBean */ public List<String> getConnectionInitSqls() { final
> List<String> result = connectionInitSqls; -        if (result ==
> null) { -            return Collections.emptyList(); -        } -
> return result; +        return result == null ?
> Collections.emptyList() : result; }
>
> /** @@ -884,10 +863,7 @@ public class BasicDataSource implements
> DataSource, BasicDataSourceMXBean, MBean */ public Set<String>
> getDisconnectionSqlCodes() { final Set<String> result =
> disconnectionSqlCodes; -        if (result == null) { -
> return Collections.emptySet(); -        } -        return result; +
> return result == null ? Collections.emptySet() : result; }
>
> /** @@ -1021,10 +997,7 @@ public class BasicDataSource implements
> DataSource, BasicDataSourceMXBean, MBean */ @Override public
> boolean getLogAbandoned() { -        if (abandonedConfig != null)
> { -            return abandonedConfig.getLogAbandoned(); -
> } -        return false; +        return abandonedConfig == null ?
> false : abandonedConfig.getLogAbandoned(); }
>
> /** @@ -1055,8 +1028,7 @@ public class BasicDataSource implements
> DataSource, BasicDataSourceMXBean, MBean */ @Override public int
> getLoginTimeout() throws SQLException { -        // This method
> isn't supported by the PoolingDataSource returned by the -
> // createDataSource +        // This method isn't supported by the
> PoolingDataSource returned by the createDataSource throw new
> UnsupportedOperationException("Not supported by BasicDataSource");
> }
>
> @@ -1170,10 +1142,7 @@ public class BasicDataSource implements
> DataSource, BasicDataSourceMXBean, MBean public int getNumActive()
> { // Copy reference to avoid NPE if close happens after null check
> final GenericObjectPool<PoolableConnection> pool = connectionPool;
> -        if (pool != null) { -            return
> pool.getNumActive(); -        } -        return 0; +        return
> pool == null ? 0 : pool.getNumActive(); }
>
> /** @@ -1185,10 +1154,7 @@ public class BasicDataSource implements
> DataSource, BasicDataSourceMXBean, MBean public int getNumIdle() {
> // Copy reference to avoid NPE if close happens after null check
> final GenericObjectPool<PoolableConnection> pool = connectionPool;
> -        if (pool != null) { -            return
> pool.getNumIdle(); -        } -        return 0; +        return
> pool == null ? 0 : pool.getNumIdle(); }
>
> /** @@ -1246,10 +1212,7 @@ public class BasicDataSource implements
> DataSource, BasicDataSourceMXBean, MBean */ @Override public
> boolean getRemoveAbandonedOnBorrow() { -        if (abandonedConfig
> != null) { -            return
> abandonedConfig.getRemoveAbandonedOnBorrow(); -        } -
> return false; +        return abandonedConfig == null ? false :
> abandonedConfig.getRemoveAbandonedOnBorrow(); }
>
> /** @@ -1270,10 +1233,7 @@ public class BasicDataSource implements
> DataSource, BasicDataSourceMXBean, MBean */ @Override public
> boolean getRemoveAbandonedOnMaintenance() { -        if
> (abandonedConfig != null) { -            return
> abandonedConfig.getRemoveAbandonedOnMaintenance(); -        } -
> return false; +        return abandonedConfig == null ? false :
> abandonedConfig.getRemoveAbandonedOnMaintenance(); }
>
> /** @@ -1298,10 +1258,7 @@ public class BasicDataSource implements
> DataSource, BasicDataSourceMXBean, MBean */ @Override public int
> getRemoveAbandonedTimeout() { -        if (abandonedConfig != null)
> { -            return abandonedConfig.getRemoveAbandonedTimeout();
> -        } -        return 300; +        return abandonedConfig ==
> null ? 300 : abandonedConfig.getRemoveAbandonedTimeout(); }
>
> /** @@ -1478,7 +1435,18 @@ public class BasicDataSource implements
> DataSource, BasicDataSourceMXBean, MBean }
>
> /** -     * If true, this data source is closed and no more
> connections can be retrieved from this datasource. +     * Returns
> true if the statement pool is cleared when the connection is
> returned to its pool. +     * +     * @return true if the statement
> pool is cleared at connection return +     * @since 2.8.0 +     */
> +    @Override +    public boolean isClearStatementPoolOnReturn()
> { +        return clearStatementPoolOnReturn; +    } + +    /** +
> * If true, this data source is closed and no more connections can
> be retrieved from this data source. * * @return true, if the data
> source is closed; false otherwise */ @@ -1591,6 +1559,31 @@ public
> class BasicDataSource implements DataSource, BasicDataSourceMXBean,
> MBean }
>
> /** +     * Restarts the datasource. +     * <p> +     * This
> method calls {@link #close()} and {@link #start()} in sequence
> within synchronized scope so any +     * connection requests that
> come in while the datsource is shutting down will be served by the
> new pool. +     * <p> +     * Idle connections that are stored in
> the connection pool when this method is invoked are closed, but +
> * connections that are checked out to clients when this method is
> invoked are not affected. When client +     * applications
> subsequently invoke {@link Connection#close()} to return these
> connections to the pool, the +     * underlying JDBC connections
> are closed. These connections do not count in {@link
> #getMaxTotal()} or +     * {@link #getNumActive()} after invoking
> this method. For example, if there are 3 connections checked out
> by +     * clients when {@link #restart()} is invoked, after this
> method is called, {@link #getNumActive()} will +     * return 0 and
> up to {@link #getMaxTotal()} + 3 connections may be open until the
> connections sourced from +     * the original pool are returned. +
> * <p> +     * The new connection pool created by this method is
> initialized with currently set configuration properties. +     * +
> * @throws SQLException if an error occurs initializing the
> datasource +     */ +    @Override +    public synchronized void
> restart() throws SQLException { +        close(); +
> start(); +    } + +    /** * Sets the print writer to be used by
> this configuration to log information on abandoned objects. * *
> @param logWriter The new log writer @@ -1655,8 +1648,6 @@ public
> class BasicDataSource implements DataSource, BasicDataSourceMXBean,
> MBean this.autoCommitOnReturn = autoCommitOnReturn; }
>
> -    // -----------------------------------------------------
> DataSource Methods - /** * Sets the state caching flag. * @@
> -1667,17 +1658,24 @@ public class BasicDataSource implements
> DataSource, BasicDataSourceMXBean, MBean }
>
> /** +     * Sets whether the pool of statements (which was enabled
> with {@link #setPoolPreparedStatements(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 ConnectionFactory class name. * * @param
> connectionFactoryClassName A class name. * @since 2.7.0 */ public
> void setConnectionFactoryClassName(final String
> connectionFactoryClassName) { -        if
> (isEmpty(connectionFactoryClassName)) { -
> this.connectionFactoryClassName = null; -        } else { -
> this.connectionFactoryClassName = connectionFactoryClassName; -
> } +        this.connectionFactoryClassName =
> isEmpty(connectionFactoryClassName) ? null :
> connectionFactoryClassName; }
>
> /** @@ -1768,11 +1766,7 @@ public class BasicDataSource implements
> DataSource, BasicDataSourceMXBean, MBean * @param defaultCatalog
> the default catalog */ public void setDefaultCatalog(final String
> defaultCatalog) { -        if (isEmpty(defaultCatalog)) { -
> this.defaultCatalog = null; -        } else { -
> this.defaultCatalog = defaultCatalog; -        } +
> this.defaultCatalog = isEmpty(defaultCatalog) ? null :
> defaultCatalog; }
>
> /** @@ -1815,11 +1809,7 @@ public class BasicDataSource implements
> DataSource, BasicDataSourceMXBean, MBean * @since 2.5.0 */ public
> void setDefaultSchema(final String defaultSchema) { -        if
> (isEmpty(defaultSchema)) { -            this.defaultSchema = null;
> -        } else { -            this.defaultSchema = defaultSchema;
> -        } +        this.defaultSchema = isEmpty(defaultSchema) ?
> null : defaultSchema; }
>
> /** @@ -1920,11 +1910,7 @@ public class BasicDataSource implements
> DataSource, BasicDataSourceMXBean, MBean * @param driverClassName
> the class name of the JDBC driver */ public synchronized void
> setDriverClassName(final String driverClassName) { -        if
> (isEmpty(driverClassName)) { -            this.driverClassName =
> null; -        } else { -            this.driverClassName =
> driverClassName; -        } +        this.driverClassName =
> isEmpty(driverClassName) ? null : driverClassName; }
>
> /** @@ -2409,11 +2395,7 @@ public class BasicDataSource implements
> DataSource, BasicDataSourceMXBean, MBean * @param validationQuery
> the new value for the validation query */ public void
> setValidationQuery(final String validationQuery) { -        if
> (isEmpty(validationQuery)) { -            this.validationQuery =
> null; -        } else { -            this.validationQuery =
> validationQuery; -        } +        this.validationQuery =
> isEmpty(validationQuery) ? null : validationQuery; }
>
> /** @@ -2432,6 +2414,29 @@ public class BasicDataSource implements
> DataSource, BasicDataSourceMXBean, MBean }
>
> /** +     * Starts the datasource. +     * <p> +     * It is not
> necessary to call this method before using a newly created
> BasicDataSource instance, but +     * calling it in that context
> causes the datasource to be immediately initialized (instead of
> waiting for +     * the first {@link #getConnection()} request).
> Its primary use is to restart and reinitialize a +     * datasource
> that has been closed. +     * <p> +     * When this method is
> called after {@link #close()}, connections checked out by clients +
> * before the datasource was stopped do not count in {@link
> #getMaxTotal()} or {@link #getNumActive()}. +     * For example, if
> there are 3 connections checked out by clients when {@link
> #close()} is invoked and they are +     * not returned before
> {@link #start()} is invoked, after this method is called, {@link
> #getNumActive()} will +     * return 0.  These connections will be
> physically closed when they are returned, but they will not count
> against +     * the maximum allowed in the newly started
> datasource. +     * +     * @throws SQLException if an error occurs
> initializing the datasource +     */ +    @Override +    public
> synchronized void start() throws SQLException { +        closed =
> false; +        createDataSource(); +    } + +    /** * Starts the
> connection pool maintenance task, if configured. */ protected void
> startPoolMaintenance() { diff --git
> a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceFactory.java
> b/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceFactory.java
> index 158b944..b8ae8f2 100644 ---
> a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceFactory.java +++
> b/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceFactory.java @@
> -100,6 +100,7 @@ public class BasicDataSourceFactory implements
> ObjectFactory { private static final String PROP_LOG_ABANDONED =
> "logAbandoned"; private static final String
> PROP_ABANDONED_USAGE_TRACKING = "abandonedUsageTracking"; private
> static final String PROP_POOL_PREPARED_STATEMENTS =
> "poolPreparedStatements"; +    private static final String
> PROP_CLEAR_STATEMENT_POOL_ON_RETURN =
> "clearStatementPoolOnReturn"; private static final String
> PROP_MAX_OPEN_PREPARED_STATEMENTS = "maxOpenPreparedStatements";
> private static final String PROP_CONNECTION_PROPERTIES =
> "connectionProperties"; private static final String
> PROP_MAX_CONN_LIFETIME_MILLIS = "maxConnLifetimeMillis"; @@ -140,6
> +141,7 @@ public class BasicDataSourceFactory implements
> ObjectFactory { PROP_URL, PROP_USER_NAME, PROP_VALIDATION_QUERY,
> PROP_VALIDATION_QUERY_TIMEOUT, PROP_CONNECTION_INIT_SQLS,
> PROP_ACCESS_TO_UNDERLYING_CONNECTION_ALLOWED,
> PROP_REMOVE_ABANDONED_ON_BORROW,
> PROP_REMOVE_ABANDONED_ON_MAINTENANCE,
> PROP_REMOVE_ABANDONED_TIMEOUT, PROP_LOG_ABANDONED,
> PROP_ABANDONED_USAGE_TRACKING, PROP_POOL_PREPARED_STATEMENTS, +
> PROP_CLEAR_STATEMENT_POOL_ON_RETURN,
> PROP_MAX_OPEN_PREPARED_STATEMENTS, PROP_CONNECTION_PROPERTIES,
> PROP_MAX_CONN_LIFETIME_MILLIS, PROP_LOG_EXPIRED_CONNECTIONS,
> PROP_ROLLBACK_ON_RETURN, PROP_ENABLE_AUTO_COMMIT_ON_RETURN,
> PROP_DEFAULT_QUERY_TIMEOUT, PROP_FAST_FAIL_VALIDATION,
> PROP_DISCONNECTION_SQL_CODES, PROP_JMX_NAME, @@ -255,7 +257,7 @@
> public class BasicDataSourceFactory implements ObjectFactory {
> final List<String> infoMessages) { final List<String>
> allPropsAsList = Arrays.asList(ALL_PROPERTIES); final String
> nameString = name != null ? "Name = " + name.toString() + " " :
> ""; -        if (NUPROP_WARNTEXT != null &&
> !NUPROP_WARNTEXT.keySet().isEmpty()) { +        if (NUPROP_WARNTEXT
> != null && !NUPROP_WARNTEXT.isEmpty()) { for (final String
> propertyName : NUPROP_WARNTEXT.keySet()) { final RefAddr ra =
> ref.get(propertyName); if (ra != null &&
> !allPropsAsList.contains(ra.getType())) { @@ -275,7 +277,7 @@
> public class BasicDataSourceFactory implements ObjectFactory {
> final String propertyName = ra.getType(); // If property name is
> not in the properties list, we haven't warned on it // and it is
> not in the "silent" list, tell user we are ignoring it. -
> if (!(allPropsAsList.contains(propertyName) ||
> NUPROP_WARNTEXT.keySet().contains(propertyName) +            if
> (!(allPropsAsList.contains(propertyName) ||
> NUPROP_WARNTEXT.containsKey(propertyName) ||
> SILENT_PROPERTIES.contains(propertyName))) { final String
> propertyValue = ra.getContent().toString(); final StringBuilder
> stringBuilder = new StringBuilder(nameString); @@ -490,6 +492,11 @@
> public class BasicDataSourceFactory implements ObjectFactory {
> dataSource.setPoolPreparedStatements(Boolean.valueOf(value).booleanVal
ue());
>
>
}
>
> +        value =
> properties.getProperty(PROP_CLEAR_STATEMENT_POOL_ON_RETURN); +
> if (value != null) { +
> dataSource.setClearStatementPoolOnReturn(Boolean.valueOf(value).boolea
nValue());
>
>
+        }
> + value =
> properties.getProperty(PROP_MAX_OPEN_PREPARED_STATEMENTS); if
> (value != null) {
> dataSource.setMaxOpenPreparedStatements(Integer.parseInt(value));
> diff --git
> a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceMXBean.java
> b/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceMXBean.java
> index 687786e..5dc6b7a 100644 ---
> a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceMXBean.java +++
> b/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceMXBean.java @@
> -16,6 +16,8 @@ */ package org.apache.tomcat.dbcp.dbcp2;
>
> +import java.sql.SQLException; + /** * Defines the methods that
> will be made available via JMX. * @@ -132,6 +134,16 @@ public
> interface BasicDataSourceMXBean { boolean
> isPoolPreparedStatements();
>
> /** +     * See {@link
> BasicDataSource#isClearStatementPoolOnReturn()} +     * +     *
> @return {@link BasicDataSource#isClearStatementPoolOnReturn()} +
> * @since 2.8.0 +     */ +    default boolean
> isClearStatementPoolOnReturn() { +        return false; +    } + +
> /** * See {@link BasicDataSource#getMaxOpenPreparedStatements()} *
> * @return {@link BasicDataSource#getMaxOpenPreparedStatements()} @@
> -315,4 +327,21 @@ public interface BasicDataSourceMXBean { * @since
> 2.1 */ String[] getDisconnectionSqlCodesAsArray(); + +    /** +
> * See {@link BasicDataSource#start()} +     * +     * @throws
> SQLException if an error occurs initializing the datasource +
> * +     * @since 2.8 +     */ +    default void start() throws
> SQLException {} + +    /** +     * See {@link
> BasicDataSource#restart()} +     * @throws SQLException if an error
> occurs initializing the datasource +     * +     * @since 2.8 +
> */ +    default 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
> c215d03..45e4dd6 100644 ---
> a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingConnection.java +++
> b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingConnection.java @@
> -532,7 +532,7 @@ public class DelegatingConnection<C extends
> Connection> extends AbandonedTrace i try {
> connection.setAutoCommit(autoCommit); if (cacheState) { -
> autoCommitCached = Boolean.valueOf(autoCommit); +
> autoCommitCached = Boolean.valueOf(connection.getAutoCommit()); } }
> catch (final SQLException e) { autoCommitCached = null; @@ -556,7
> +556,7 @@ public class DelegatingConnection<C extends Connection>
> extends AbandonedTrace i try { connection.setReadOnly(readOnly); if
> (cacheState) { -                readOnlyCached =
> Boolean.valueOf(readOnly); +                readOnlyCached =
> Boolean.valueOf(connection.isReadOnly()); } } catch (final
> SQLException e) { readOnlyCached = null; diff --git
> a/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnection.java
> b/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnection.java index
> 9c15c7e..bdca159 100644 ---
> a/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnection.java +++
> b/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnection.java @@
> -124,6 +124,9 @@ public class PoolableConnection extends
> DelegatingConnection<Connection> impleme protected void passivate()
> throws SQLException { super.passivate(); setClosedInternal(true); +
> if (getDelegateInternal() instanceof PoolingConnection) { +
> ((PoolingConnection)
> getDelegateInternal()).connectionReturnedToPool(); +        } }
>
> /** diff --git
> a/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionFactory.java
> b/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionFactory.java
> index 4123d16..b25bb9a 100644 ---
> a/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionFactory.java
> +++
> b/java/org/apache/tomcat/dbcp/dbcp2/PoolableConnectionFactory.java
> @@ -84,6 +84,8 @@ public class PoolableConnectionFactory implements
> PooledObjectFactory<PoolableCo
>
> private boolean poolStatements;
>
> +    private boolean clearStatementPoolOnReturn; + private int
> maxOpenPreparedStatements =
> GenericKeyedObjectPoolConfig.DEFAULT_MAX_TOTAL_PER_KEY;
>
> private long maxConnLifetimeMillis = -1; @@ -392,6 +394,7 @@ public
> class PoolableConnectionFactory implements
> PooledObjectFactory<PoolableCo final KeyedObjectPool<PStmtKey,
> DelegatingPreparedStatement> stmtPool = new
> GenericKeyedObjectPool<>( poolingConn, config);
> poolingConn.setStatementPool(stmtPool); +
> poolingConn.setClearStatementPoolOnReturn(clearStatementPoolOnReturn);
>
>
poolingConn.setCacheState(cacheState);
> }
>
> @@ -597,6 +600,17 @@ 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/PoolingConnection.java
> b/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java index
> 86e6d4e..8615074 100644 ---
> a/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java +++
> b/java/org/apache/tomcat/dbcp/dbcp2/PoolingConnection.java @@ -65,6
> +65,8 @@ public class PoolingConnection extends
> DelegatingConnection<Connection> /** Pool of {@link
> PreparedStatement}s. and {@link CallableStatement}s */ private
> KeyedObjectPool<PStmtKey, DelegatingPreparedStatement> pstmtPool;
>
> +    private boolean clearStatementPoolOnReturn = false; + /** *
> Constructor. * @@ -117,6 +119,23 @@ public class PoolingConnection
> extends DelegatingConnection<Connection> }
>
> /** +     * Notification from {@link PoolableConnection} that we
> returned to the pool. +     * +     * @throws SQLException when
> <code>clearStatementPoolOnReturn</code> is true and the statement
> pool could not be +     *                      cleared +     *
> @since 2.8.0 +     */ +    public void connectionReturnedToPool()
> throws SQLException { +        if (pstmtPool != null &&
> clearStatementPoolOnReturn) { +            try { +
> pstmtPool.clear(); +            } catch (Exception e) { +
> throw new SQLException("Error clearing statement pool", e); +
> } +        } +    } + +    /** * Creates a PStmtKey for the given
> arguments. * * @param sql @@ -134,7 +153,8 @@ public class
> PoolingConnection extends DelegatingConnection<Connection> * @param
> sql *            the SQL string used to define the statement *
> @param columnIndexes -     *            column indexes +     *
> An array of column indexes indicating the columns that should be
> returned from the inserted row or +     *            rows. * *
> @return the PStmtKey created for the given arguments. */ @@ -142,6
> +162,17 @@ public class PoolingConnection extends
> DelegatingConnection<Connection> return new
> PStmtKey(normalizeSQL(sql), getCatalogOrNull(), getSchemaOrNull(),
> columnIndexes); }
>
> +    /** +     * Creates a PStmtKey for the given arguments. +
> * +     * @param sql +     *            the SQL string used to
> define the statement +     * @param autoGeneratedKeys +     *
> 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
> the PStmtKey created for the given arguments. +     */ protected
> PStmtKey createKey(final String sql, final int autoGeneratedKeys)
> { return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(),
> getSchemaOrNull(), autoGeneratedKeys); } @@ -277,13 +308,23 @@
> public class PoolingConnection extends
> DelegatingConnection<Connection> }
>
> private String getSchemaOrNull() { -        String catalog = null;
> +        String schema = null; try { -            catalog =
> getSchema(); +            schema = getSchema(); } catch (final
> SQLException e) { // Ignored } -        return catalog; +
> return schema; +    } + +    /** +     * Returns the prepared
> statement pool we're using. +     * +     * @return statement pool
> +     * @since 2.8.0 +     */ +    public KeyedObjectPool<PStmtKey,
> DelegatingPreparedStatement> getStatementPool() { +        return
> pstmtPool; }
>
> /** @@ -342,6 +383,19 @@ public class PoolingConnection extends
> DelegatingConnection<Connection> /** * Creates or obtains a {@link
> CallableStatement} from the pool. * +     * @param key +     *
> a {@link PStmtKey} for the given arguments +     * @return a {@link
> PoolableCallableStatement} +     * @throws SQLException +     *
> Wraps an underlying exception. +     */ +    private
> CallableStatement prepareCall(final PStmtKey key) throws
> SQLException { +        return (CallableStatement)
> prepareStatement(key); +    } + +    /** +     * Creates or obtains
> a {@link CallableStatement} from the pool. +     * * @param sql *
> the SQL string used to define the CallableStatement * @return a
> {@link PoolableCallableStatement} @@ -350,15 +404,7 @@ public class
> PoolingConnection extends DelegatingConnection<Connection> */
> @Override public CallableStatement prepareCall(final String sql)
> throws SQLException { -        try { -            return
> (CallableStatement) pstmtPool.borrowObject(createKey(sql,
> 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); -
> } +        return prepareCall(createKey(sql,
> StatementType.CALLABLE_STATEMENT)); }
>
> /** @@ -377,16 +423,7 @@ public class PoolingConnection extends
> DelegatingConnection<Connection> @Override public CallableStatement
> prepareCall(final String sql, final int resultSetType, final int
> resultSetConcurrency) throws SQLException { -        try { -
> return (CallableStatement) pstmtPool.borrowObject( -
> createKey(sql, resultSetType, resultSetConcurrency,
> 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); -
> } +        return prepareCall(createKey(sql, resultSetType,
> resultSetConcurrency, StatementType.CALLABLE_STATEMENT)); }
>
> /** @@ -407,32 +444,25 @@ public class PoolingConnection extends
> DelegatingConnection<Connection> @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); -
> } +        return prepareCall(createKey(sql, resultSetType,
> resultSetConcurrency, +                resultSetHoldability,
> StatementType.CALLABLE_STATEMENT)); }
>
> /** * Creates or obtains a {@link PreparedStatement} from the
> pool. * -     * @param sql -     *            the SQL string used
> to define the PreparedStatement +     * @param key +     *
> a {@link PStmtKey} for the given arguments * @return a {@link
> PoolablePreparedStatement} +     * @throws SQLException +     *
> Wraps an underlying exception. */ -    @Override -    public
> PreparedStatement prepareStatement(final String sql) throws
> SQLException { +    private PreparedStatement
> prepareStatement(final PStmtKey key) throws SQLException { if (null
> == pstmtPool) { throw new SQLException("Statement pool is null -
> closed or invalid PoolingConnection."); } try { -            return
> pstmtPool.borrowObject(createKey(sql)); +            return
> pstmtPool.borrowObject(key); } catch (final NoSuchElementException
> e) { throw new SQLException("MaxOpenPreparedStatements limit
> reached", e); } catch (final RuntimeException e) { @@ -442,20
> +472,35 @@ public class PoolingConnection extends
> DelegatingConnection<Connection> } }
>
> +    /** +     * Creates or obtains a {@link PreparedStatement}
> from the pool. +     * +     * @param sql +     *            the
> SQL string used to define the PreparedStatement +     * @return a
> {@link PoolablePreparedStatement} +     * @throws SQLException +
> *             Wraps an underlying exception. +     */ +
> @Override +    public PreparedStatement prepareStatement(final
> String sql) throws SQLException { +        return
> prepareStatement(createKey(sql)); +    } + +    /* +     * Creates
> or obtains a {@link PreparedStatement} from the pool. +     * +
> * @param sql +     *            the SQL string used to define the
> PreparedStatement +     * @param autoGeneratedKeys +     *
> 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 +     *
> Wraps an underlying exception. +     */ @Override public
> PreparedStatement prepareStatement(final String sql, final int
> autoGeneratedKeys) throws SQLException { -        if (null ==
> pstmtPool) { -            throw new SQLException("Statement pool is
> null - closed or invalid PoolingConnection."); -        } -
> try { -            return pstmtPool.borrowObject(createKey(sql,
> autoGeneratedKeys)); -        } 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); -
> } +        return prepareStatement(createKey(sql,
> autoGeneratedKeys)); }
>
> /** @@ -464,23 +509,16 @@ public class PoolingConnection extends
> DelegatingConnection<Connection> * @param sql *            the SQL
> string used to define the PreparedStatement * @param columnIndexes
> -     *            column indexes +     *            An array of
> column indexes indicating the columns that should be returned from
> the inserted row or +     *            rows. * @return a {@link
> PoolablePreparedStatement} +     * @throws SQLException +     *
> Wraps an underlying exception. +     * */ @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); -
> } +        return prepareStatement(createKey(sql, columnIndexes));
> }
>
> /** @@ -493,22 +531,13 @@ public class PoolingConnection extends
> DelegatingConnection<Connection> * @param resultSetConcurrency *
> result set concurrency * @return a {@link
> PoolablePreparedStatement} +     * @throws SQLException +     *
> Wraps an underlying exception. */ @Override public
> PreparedStatement prepareStatement(final String sql, final int
> resultSetType, final int resultSetConcurrency) throws SQLException
> { -        if (null == pstmtPool) { -            throw new
> SQLException("Statement pool is null - closed or invalid
> PoolingConnection."); -        } -        try { -            return
> pstmtPool.borrowObject(createKey(sql, resultSetType,
> resultSetConcurrency)); -        } 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); -
> } +        return prepareStatement(createKey(sql, resultSetType,
> resultSetConcurrency)); }
>
> /** @@ -523,22 +552,13 @@ public class PoolingConnection extends
> DelegatingConnection<Connection> * @param resultSetHoldability *
> result set holdability * @return a {@link
> PoolablePreparedStatement} +     * @throws SQLException +     *
> Wraps an underlying exception. */ @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); -
> } +        return prepareStatement(createKey(sql, resultSetType,
> resultSetConcurrency, resultSetHoldability)); }
>
> /** @@ -549,21 +569,23 @@ public class PoolingConnection extends
> DelegatingConnection<Connection> * @param columnNames *
> column names * @return a {@link PoolablePreparedStatement} +     *
> @throws SQLException +     *             Wraps an underlying
> exception. */ @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); -
> } +        return prepareStatement(createKey(sql, columnNames)); +
> } + +    /** +     * Sets whether the pool of statements 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; }
>
> /** diff --git
> a/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java
> b/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java
>
>
index 34bad40..772682f 100644
> ---
> a/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java
>
>
+++ b/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.ja
va
> @@ -37,6 +37,7 @@ import javax.naming.spi.ObjectFactory; import
> javax.sql.ConnectionPoolDataSource; import
> javax.sql.PooledConnection;
>
> +import org.apache.tomcat.dbcp.dbcp2.BasicDataSource; import
> org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement; import
> org.apache.tomcat.dbcp.dbcp2.PStmtKey; import
> org.apache.tomcat.dbcp.dbcp2.Utils; @@ -621,17 +622,15 @@ public
> class DriverAdapterCPDS implements ConnectionPoolDataSource,
> Referenceabl /** * Sets the number of statements to examine during
> each run of the idle object evictor thread (if any). * <p> -     *
> When a negative value is supplied, <code>ceil({*link
> #numIdle})/abs({*link #getNumTestsPerEvictionRun})</code> -     *
> tests will be run. I.e., when the value is <i>-n</i>, roughly one
> <i>n</i>th of the idle objects will be tested -     * per run. +
> * When a negative value is supplied, +     * <code>ceil({@link
> BasicDataSource#getNumIdle})/abs({@link
> #getNumTestsPerEvictionRun})</code> tests will be run. +     *
> I.e., when the value is <i>-n</i>, roughly one <i>n</i>th of the
> idle objects will be tested per run. * </p> * -     * @param
> numTestsPerEvictionRun -     *            number of statements to
> examine per run +     * @param numTestsPerEvictionRun number of
> statements to examine per run * @see #getNumTestsPerEvictionRun() *
> @see #setTimeBetweenEvictionRunsMillis(long) -     * @throws
> IllegalStateException -     *             if {@link
> #getPooledConnection()} has been called +     * @throws
> IllegalStateException if {@link #getPooledConnection()} has been
> called */ public void setNumTestsPerEvictionRun(final int
> numTestsPerEvictionRun) { assertInitializationAllowed(); @@ -755,11
> +754,8 @@ public class DriverAdapterCPDS implements
> ConnectionPoolDataSource, Referenceabl
> builder.append(getConnectionCalled); builder.append(",
> connectionProperties="); Properties tmpProps =
> connectionProperties; -        final String pwdKey = "password"; -
> if (connectionProperties != null &&
> connectionProperties.contains(pwdKey)) { -            tmpProps =
> (Properties) connectionProperties.clone(); -
> tmpProps.remove(pwdKey); -        } +        tmpProps =
> mask(tmpProps, "user"); +        tmpProps = mask(tmpProps,
> "password"); builder.append(tmpProps); builder.append(",
> accessToUnderlyingConnectionAllowed=");
> builder.append(accessToUnderlyingConnectionAllowed); @@ -767,6
> +763,14 @@ public class DriverAdapterCPDS implements
> ConnectionPoolDataSource, Referenceabl 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/datasources/CPDSConnectionFactory.
java
> b/java/org/apache/tomcat/dbcp/dbcp2/datasources/CPDSConnectionFactory.
java
>
>
index 915e4cd..93363a4 100644
> ---
> a/java/org/apache/tomcat/dbcp/dbcp2/datasources/CPDSConnectionFactory.
java
>
>
+++
b/java/org/apache/tomcat/dbcp/dbcp2/datasources/CPDSConnectionFactory.ja
va
> @@ -37,8 +37,7 @@ import
> org.apache.tomcat.dbcp.pool2.PooledObjectFactory; import
> org.apache.tomcat.dbcp.pool2.impl.DefaultPooledObject;
>
> /** - * A {@link PooledObjectFactory} that creates - * {@link
> org.apache.tomcat.dbcp.dbcp2.PoolableConnection
> PoolableConnection}s. + * A {@link PooledObjectFactory} that
> creates {@link org.apache.tomcat.dbcp.dbcp2.PoolableConnection
> PoolableConnection}s. * * @since 2.0 */ diff --git
> a/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSource.
java
> b/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSource.
java
>
>
index 69d6eff..8168bcc 100644
> ---
> a/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSource.
java
>
>
+++
b/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSource.ja
va
> @@ -532,7 +532,7 @@ public abstract class InstanceKeyDataSource
> implements DataSource, Referenceable }
>
> /** -     * Sets the backend ConnectionPoolDataSource. This
> property should not be set if using JNDI to access the +     * Sets
> the back end ConnectionPoolDataSource. This property should not be
> set if using JNDI to access the * data source. * * @param v @@
> -689,7 +689,7 @@ public abstract class InstanceKeyDataSource
> implements DataSource, Referenceable
>
> /** * Gets the value of jndiEnvironment which is used when
> instantiating a JNDI InitialContext. This InitialContext is -     *
> used to locate the backend ConnectionPoolDataSource. +     * used
> to locate the back end ConnectionPoolDataSource. * * @param key *
> JNDI environment key. @@ -705,7 +705,7 @@ public abstract class
> InstanceKeyDataSource implements DataSource, Referenceable
>
> /** * Sets the value of the given JNDI environment property to be
> used when instantiating a JNDI InitialContext. This -     *
> InitialContext is used to locate the backend
> ConnectionPoolDataSource. +     * InitialContext is used to locate
> the back end ConnectionPoolDataSource. * * @param key *
> the JNDI environment property to set. @@ -721,7 +721,7 @@ public
> abstract class InstanceKeyDataSource implements DataSource,
> Referenceable
>
> /** * Sets the JNDI environment to be used when instantiating a
> JNDI InitialContext. This InitialContext is used to -     * locate
> the backend ConnectionPoolDataSource. +     * locate the back end
> ConnectionPoolDataSource. * * @param properties *            the
> JNDI environment property to set which will overwrite any current
> settings 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 6395e29..531db68 100644 ---
> a/java/org/apache/tomcat/dbcp/dbcp2/datasources/package-info.java
> +++
> b/java/org/apache/tomcat/dbcp/dbcp2/datasources/package-info.java
> @@ -127,7 +127,7 @@ * Connection pooling is useful in applications
> regardless of whether they run * in a J2EE environment and a
> <code>DataSource</code> can be used within a * simpler environment.
> The example below shows SharedPoolDataSource using - *
> DriverAdapterCPDS as the backend source, though any CPDS is
> applicable. + * DriverAdapterCPDS as the back end source, though
> any CPDS is applicable. * </p> * * <code> diff --git
> a/java/org/apache/tomcat/dbcp/dbcp2/managed/BasicManagedDataSource.jav
a
> b/java/org/apache/tomcat/dbcp/dbcp2/managed/BasicManagedDataSource.jav
a
>
>
index 0db3393..17ecca9 100644
> ---
> a/java/org/apache/tomcat/dbcp/dbcp2/managed/BasicManagedDataSource.jav
a
>
>
+++ b/java/org/apache/tomcat/dbcp/dbcp2/managed/BasicManagedDataSource.j
ava
> @@ -175,7 +175,7 @@ public class BasicManagedDataSource extends
> BasicDataSource { if (xaDataSource == null) { final
> ConnectionFactory connectionFactory =
> super.createConnectionFactory(); final XAConnectionFactory
> xaConnectionFactory = new
> LocalXAConnectionFactory(getTransactionManager(), -
> connectionFactory); +
> getTransactionSynchronizationRegistry(), connectionFactory);
> transactionRegistry =
> xaConnectionFactory.getTransactionRegistry(); return
> xaConnectionFactory; } @@ -238,6 +238,7 @@ public class
> BasicManagedDataSource extends BasicDataSource {
> connectionFactory.setDefaultSchema(getDefaultSchema());
> connectionFactory.setCacheState(getCacheState());
> connectionFactory.setPoolStatements(isPoolPreparedStatements()); +
> connectionFactory.setClearStatementPoolOnReturn(isClearStatementPoolOn
Return());
>
>
connectionFactory.setMaxOpenPreparedStatements(getMaxOpenPreparedStateme
nts());
> connectionFactory.setMaxConnLifetimeMillis(getMaxConnLifetimeMillis())
;
>
>
connectionFactory.setRollbackOnReturn(getRollbackOnReturn());
> diff --git
> a/java/org/apache/tomcat/dbcp/dbcp2/managed/LocalXAConnectionFactory.j
ava
> b/java/org/apache/tomcat/dbcp/dbcp2/managed/LocalXAConnectionFactory.j
ava
>
>
index 5eda07d..23e7283 100644
> ---
> a/java/org/apache/tomcat/dbcp/dbcp2/managed/LocalXAConnectionFactory.j
ava
>
>
+++
b/java/org/apache/tomcat/dbcp/dbcp2/managed/LocalXAConnectionFactory.jav
a
> @@ -26,6 +26,7 @@ import javax.transaction.xa.XAResource; import
> javax.transaction.xa.Xid;
>
> import jakarta.transaction.TransactionManager; +import
> jakarta.transaction.TransactionSynchronizationRegistry;
>
> import org.apache.tomcat.dbcp.dbcp2.ConnectionFactory;
>
> @@ -317,9 +318,27 @@ public class LocalXAConnectionFactory
> implements XAConnectionFactory { */ public
> LocalXAConnectionFactory(final TransactionManager
> transactionManager, final ConnectionFactory connectionFactory) { +
> this(transactionManager, null, connectionFactory); +    } + +
> /** +     * Creates an LocalXAConnectionFactory which uses the
> specified connection factory to create database connections. +
> * The connections are enlisted into transactions using the
> specified transaction manager. +     * +     * @param
> transactionManager +     *            the transaction manager in
> which connections will be enlisted +     * @param
> transactionSynchronizationRegistry +     *            the optional
> TSR to register synchronizations with +     * @param
> connectionFactory +     *            the connection factory from
> which connections will be retrieved +     * @since 2.8.0 +     */ +
> public LocalXAConnectionFactory(final TransactionManager
> transactionManager, +            final
> TransactionSynchronizationRegistry
> transactionSynchronizationRegistry, +            final
> ConnectionFactory connectionFactory) {
> Objects.requireNonNull(transactionManager, "transactionManager is
> null"); Objects.requireNonNull(connectionFactory,
> "connectionFactory is null"); -        this.transactionRegistry =
> new TransactionRegistry(transactionManager); +
> this.transactionRegistry = new
> TransactionRegistry(transactionManager,
> transactionSynchronizationRegistry); this.connectionFactory =
> connectionFactory; }
>
> diff --git a/webapps/docs/changelog.xml
> b/webapps/docs/changelog.xml index 0d64135..1bc6937 100644 ---
> a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@
> -219,6 +219,10 @@ Update the internal fork of Apache Commons Pool
> to 2.8.1. Code clean-up and improved abandoned pool handling.
> (markt) </add> +      <add> +        Update the internal fork of
> Apache Commons DBCP to 6d232e5 (2020-08-11, +
> 2.8.0-SNAPSHOT). Code clean-up various bug fixes. (markt) +
> </add> </changelog> </subsection> </section>
>
>
> ---------------------------------------------------------------------
>
>
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: dev-h...@tomcat.apache.org
>
-----BEGIN PGP SIGNATURE-----
Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/

iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAl9GlFAACgkQHPApP6U8
pFhPMg/+NORUcXAQAB4fF8deGKO2SUBf7ZSV9mnoNtzt7xOPU90qAWeu/tUWshBR
+8tM8ya9xVgUSEgPskjUGcRCmiGn/fC1o76VMLXr/WNDJmdzty7xVvzkrY5Wn6Vf
CoKpB7hd7tEFECt1h+NU5iEmgiGFr/3A3qmK++YXU1hzKPjiENWhYZrkd4A1bjOR
XEZh+pzeadSkB25YtS0GP7ea/FeDx2xyQ9bD4nRLHDFrbIJzW077q+DSVug0zukR
FA/8nfjoU1ajIPJ7ZrJz/P0IfMMACuz6jXNcVF2opm/CILyav44SQ+JLDDGTpZ1N
tNtLpn0HU5efxzNKiqrJ+7/UVbwHwRt3cIS+RfxMDHvyUPq3cFWpx8EogDbRzH/V
HkUBHyssxwxmD9SPc1zCI/pdEbA6tsH3e3XcD0P4FQdcG4uKB43GfCNS/vo6M4NP
/ekU6WyO+5pVD5uKSKn/4i8hW6KKo8G6nzxYBvfR+xZ8KFf+yikN/GigwMjJ5qJp
VkYgmWNW2eXKC/fplYguOH0i5l1jjn30Y0xETXGnaLp+Q+MbSjqQcs0YprveRbPo
JU7+vCMIfMI7RJOJT1+kLNmP7Yj99+JYmypDV41xo3B0e7rhiquTiRpJa2A4jELq
ARWYmS21yGHTnTngI9wWrB/bhSTio2bnaSPNtzg6NSX3PCzF/lY=
=yGdr
-----END PGP SIGNATURE-----

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

Reply via email to