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
The following commit(s) were added to refs/heads/master by this push:
new 799345a Update Commons DBCP2
799345a is described below
commit 799345aa5a0dcce468fe27f65c9129431c9bbf82
Author: Mark Thomas <[email protected]>
AuthorDate: Thu Aug 1 22:09:08 2019 +0100
Update Commons DBCP2
---
MERGE.txt | 2 +-
.../apache/tomcat/dbcp/dbcp2/AbandonedTrace.java | 14 +-
.../apache/tomcat/dbcp/dbcp2/BasicDataSource.java | 444 ++++++-------
.../tomcat/dbcp/dbcp2/BasicDataSourceFactory.java | 9 +-
.../dbcp/dbcp2/ConnectionFactoryFactory.java | 77 +++
.../tomcat/dbcp/dbcp2/DelegatingConnection.java | 67 +-
.../tomcat/dbcp/dbcp2/DelegatingResultSet.java | 4 +-
.../tomcat/dbcp/dbcp2/DelegatingStatement.java | 57 +-
.../tomcat/dbcp/dbcp2/DriverConnectionFactory.java | 2 +
.../apache/tomcat/dbcp/dbcp2/DriverFactory.java | 81 +++
.../org/apache/tomcat/dbcp/dbcp2/Jdbc41Bridge.java | 2 +-
.../dbcp/dbcp2/PoolableCallableStatement.java | 29 +-
.../dbcp/dbcp2/PoolablePreparedStatement.java | 33 +-
.../apache/tomcat/dbcp/dbcp2/SQLExceptionList.java | 51 ++
.../dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java | 691 +++++++++++----------
.../dbcp2/cpdsadapter/PooledConnectionImpl.java | 81 +++
.../dbcp2/datasources/InstanceKeyDataSource.java | 20 +-
.../datasources/InstanceKeyDataSourceFactory.java | 2 +-
webapps/docs/changelog.xml | 4 +
19 files changed, 988 insertions(+), 682 deletions(-)
diff --git a/MERGE.txt b/MERGE.txt
index dd72706..396405a 100644
--- a/MERGE.txt
+++ b/MERGE.txt
@@ -63,7 +63,7 @@ Sub-tree
src/main/java/org/apache/commons/dbcp2
src/main/resources/org/apache/commons/dbcp2
The SHA1 ID for the most recent commit to be merged to Tomcat is:
-dcdbc72acf51155d2a6c3f10461d9712a3623686 (2019-04-24)
+87d9e3a66b896d81339a0947d001837ad2651605 (2019-08-01)
Pool2
Sub-tree
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/AbandonedTrace.java
b/java/org/apache/tomcat/dbcp/dbcp2/AbandonedTrace.java
index ea6d5a2..3969480 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/AbandonedTrace.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/AbandonedTrace.java
@@ -155,7 +155,7 @@ public class AbandonedTrace implements TrackedUse {
final Iterator<WeakReference<AbandonedTrace>> iter =
traceList.iterator();
while (iter.hasNext()) {
final AbandonedTrace traceInList = iter.next().get();
- if (trace.equals(traceInList)) {
+ if (trace != null && trace.equals(traceInList)) {
iter.remove();
break;
} else if (traceInList == null) {
@@ -165,4 +165,16 @@ public class AbandonedTrace implements TrackedUse {
}
}
}
+
+ /**
+ * Removes this object the source object is tracing.
+ *
+ * @param source The object tracing
+ * @since 2.7.0
+ */
+ protected void removeThisTrace(final Object source) {
+ if (source instanceof AbandonedTrace) {
+ AbandonedTrace.class.cast(source).removeTrace(this);
+ }
+ }
}
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.java
b/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.java
index ba3e38a..6345a22 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSource.java
@@ -76,8 +76,6 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
private static final Log log = LogFactory.getLog(BasicDataSource.class);
- // ------------------------------------------------------------- Properties
-
static {
// Attempt to prevent deadlocks - see DBCP - 272
DriverManager.getDrivers();
@@ -108,6 +106,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
}
}
+ @SuppressWarnings("resource")
protected static void validateConnectionFactory(final
PoolableConnectionFactory connectionFactory)
throws Exception {
PoolableConnection conn = null;
@@ -315,6 +314,11 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
private volatile int validationQueryTimeoutSeconds = -1;
/**
+ * The fully qualified Java class name of a {@link ConnectionFactory}
implementation.
+ */
+ private String connectionFactoryClassName;
+
+ /**
* These SQL statements run once after a Connection is created.
* <p>
* This property can be used for example to run ALTER SESSION SET
NLS_SORT=XCYECH in an Oracle Database only once
@@ -380,10 +384,8 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* be called before the first connection is retrieved (along with all the
other configuration property setters).
* Calls to this method after the connection pool has been initialized
have no effect.
*
- * @param name
- * Name of the custom connection property
- * @param value
- * Value of the custom connection property
+ * @param name Name of the custom connection property
+ * @param value Value of the custom connection property
*/
public void addConnectionProperty(final String name, final String value) {
connectionProperties.put(name, value);
@@ -408,8 +410,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* exceptions.
* </p>
*
- * @throws SQLException
- * if an error occurs closing idle connections
+ * @throws SQLException if an error occurs closing idle connections
*/
@Override
public synchronized void close() throws SQLException {
@@ -458,77 +459,17 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* context class loader of the current thread.</li>
* <li>If a driver still isn't loaded one is loaded via the {@link
DriverManager} using the specified {@link #url}.
* </ol>
+ * <p>
* This method exists so subclasses can replace the implementation class.
+ * </p>
*
* @return A new connection factory.
*
- * @throws SQLException
- * If the connection factort cannot be created
+ * @throws SQLException If the connection factort cannot be created
*/
protected ConnectionFactory createConnectionFactory() throws SQLException {
// Load the JDBC driver class
- Driver driverToUse = this.driver;
-
- if (driverToUse == null) {
- Class<?> driverFromCCL = null;
- if (driverClassName != null) {
- try {
- try {
- if (driverClassLoader == null) {
- driverFromCCL = Class.forName(driverClassName);
- } else {
- driverFromCCL = Class.forName(driverClassName,
true, driverClassLoader);
- }
- } catch (final ClassNotFoundException cnfe) {
- driverFromCCL =
Thread.currentThread().getContextClassLoader().loadClass(driverClassName);
- }
- } catch (final Exception t) {
- final String message = "Cannot load JDBC driver class '" +
driverClassName + "'";
- logWriter.println(message);
- t.printStackTrace(logWriter);
- throw new SQLException(message, t);
- }
- }
-
- try {
- if (driverFromCCL == null) {
- driverToUse = DriverManager.getDriver(url);
- } else {
- // Usage of DriverManager is not possible, as it does not
- // respect the ContextClassLoader
- // N.B. This cast may cause ClassCastException which is
handled below
- driverToUse = (Driver)
driverFromCCL.getConstructor().newInstance();
- if (!driverToUse.acceptsURL(url)) {
- throw new SQLException("No suitable driver", "08001");
- }
- }
- } catch (final Exception t) {
- final String message = "Cannot create JDBC driver of class '"
- + (driverClassName != null ? driverClassName : "") +
"' for connect URL '" + url + "'";
- logWriter.println(message);
- t.printStackTrace(logWriter);
- throw new SQLException(message, t);
- }
- }
-
- // Set up the driver connection factory we will use
- final String user = userName;
- if (user != null) {
- connectionProperties.put("user", user);
- } else {
- log("DBCP DataSource configured without a 'username'");
- }
-
- final String pwd = password;
- if (pwd != null) {
- connectionProperties.put("password", pwd);
- } else {
- log("DBCP DataSource configured without a 'password'");
- }
-
- final ConnectionFactory driverConnectionFactory = new
DriverConnectionFactory(driverToUse, url,
- connectionProperties);
- return driverConnectionFactory;
+ return ConnectionFactoryFactory.createConnectionFactory(this,
DriverFactory.createDriver(this));
}
/**
@@ -540,8 +481,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* positive value causes {@link GenericObjectPool}'s eviction timer to be
started.
* </p>
*
- * @param factory
- * The factory to use to create new connections for this pool.
+ * @param factory The factory to use to create new connections for this
pool.
*/
protected void createConnectionPool(final PoolableConnectionFactory
factory) {
// Create an object pool to contain our active connections
@@ -574,8 +514,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* </p>
*
* @return The current internal DataSource or a newly created instance if
it has not yet been created.
- * @throws SQLException
- * if the object pool cannot be created.
+ * @throws SQLException if the object pool cannot be created.
*/
protected DataSource createDataSource() throws SQLException {
if (closed) {
@@ -648,7 +587,8 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
throw new SQLException("Error preloading the connection pool",
e);
}
- // If timeBetweenEvictionRunsMillis > 0, start the pool's evictor
task
+ // If timeBetweenEvictionRunsMillis > 0, start the pool's evictor
+ // task
startPoolMaintenance();
dataSource = newDataSource;
@@ -660,8 +600,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* Creates the actual data source instance. This method only exists so
that subclasses can replace the
* implementation class.
*
- * @throws SQLException
- * if unable to create a datasource instance
+ * @throws SQLException if unable to create a datasource instance
*
* @return A new DataSource instance
*/
@@ -674,12 +613,9 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
/**
* 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
+ * @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,
@@ -698,10 +634,8 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* Creates the PoolableConnectionFactory and attaches it to the connection
pool. This method only exists so
* subclasses can replace the default implementation.
*
- * @param driverConnectionFactory
- * JDBC connection factory
- * @throws SQLException
- * if an error occurs creating the PoolableConnectionFactory
+ * @param driverConnectionFactory JDBC connection factory
+ * @throws SQLException if an error occurs creating the
PoolableConnectionFactory
*
* @return A new PoolableConnectionFactory configured with the current
configuration of this BasicDataSource
*/
@@ -738,6 +672,17 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
}
/**
+ * Manually evicts idle connections
+ *
+ * @throws Exception when there is a problem evicting idle objects.
+ */
+ public void evict() throws Exception {
+ if (connectionPool != null) {
+ connectionPool.evict();
+ }
+ }
+
+ /**
* Gets the print writer used by this configuration to log information on
abandoned objects.
*
* @return The print writer used by this configuration to log information
on abandoned objects.
@@ -788,8 +733,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
/**
* Creates (if necessary) and return a connection to the database.
*
- * @throws SQLException
- * if a database access error occurs
+ * @throws SQLException if a database access error occurs
* @return a database connection
*/
@Override
@@ -812,24 +756,34 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
/**
* <strong>BasicDataSource does NOT support this method.</strong>
*
- * @param user
- * Database user on whose behalf the Connection is being made
- * @param pass
- * The database user's password
+ * @param user Database user on whose behalf the Connection is being made
+ * @param pass The database user's password
*
- * @throws UnsupportedOperationException
- * always thrown.
- * @throws SQLException
- * if a database access error occurs
+ * @throws UnsupportedOperationException always thrown.
+ * @throws SQLException if a database access error occurs
* @return nothing - always throws UnsupportedOperationException
*/
@Override
public Connection getConnection(final String user, final String pass)
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");
}
/**
+ * Returns the ConnectionFactoryClassName that has been configured for use
by this pool.
+ * <p>
+ * Note: This getter only returns the last value set by a call to {@link
#setConnectionFactoryClassName(String)}.
+ * </p>
+ *
+ * @return the ConnectionFactoryClassName that has been configured for use
by this pool.
+ * @since 2.7.0
+ */
+ public String getConnectionFactoryClassName() {
+ return this.connectionFactoryClassName;
+ }
+
+ /**
* Returns the list of SQL statements executed when a physical connection
is first created. Returns an empty list if
* there are no initialization statements configured.
*
@@ -856,7 +810,6 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
return connectionPool;
}
- // For unit testing
Properties getConnectionProperties() {
return connectionProperties;
}
@@ -1096,15 +1049,15 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* Calls {@link #createDataSource()}, so has the side effect of
initializing the connection pool.
* </p>
*
- * @throws SQLException
- * if a database access error occurs
- * @throws UnsupportedOperationException
- * If the DataSource implementation does not support the login
timeout feature.
+ * @throws SQLException if a database access error occurs
+ * @throws UnsupportedOperationException If the DataSource implementation
does not support the login timeout
+ * feature.
* @return login timeout in seconds
*/
@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");
}
@@ -1116,8 +1069,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* Calls {@link #createDataSource()}, so has the side effect of
initializing the connection pool.
* </p>
*
- * @throws SQLException
- * if a database access error occurs
+ * @throws SQLException if a database access error occurs
* @return log writer in use
*/
@Override
@@ -1485,13 +1437,12 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* Manually invalidates a connection, effectively requesting the pool to
try to close it, remove it from the pool
* and reclaim pool capacity.
*
- * @param connection
- * The Connection to invalidate.
+ * @param connection The Connection to invalidate.
*
- * @throws IllegalStateException
- * if invalidating the connection failed.
+ * @throws IllegalStateException if invalidating the connection failed.
* @since 2.1
*/
+ @SuppressWarnings("resource")
public void invalidateConnection(final Connection connection) throws
IllegalStateException {
if (connection == null) {
return;
@@ -1519,18 +1470,6 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
}
/**
- * Manually evicts idle connections.
- *
- * @throws Exception Thrown by {@link GenericObjectPool#evict()}.
- * @see GenericObjectPool#evict()
- */
- public void evict() throws Exception {
- if (connectionPool != null) {
- connectionPool.evict();
- }
- }
-
- /**
* Returns the value of the accessToUnderlyingConnectionAllowed property.
*
* @return true if access to the underlying connection is allowed, false
otherwise.
@@ -1551,6 +1490,16 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
}
/**
+ * Delegates in a null-safe manner to {@link String#isEmpty()}.
+ *
+ * @param value the string to test, may be null.
+ * @return boolean false if value is null, otherwise {@link
String#isEmpty()}.
+ */
+ private boolean isEmpty(String value) {
+ return value == null ? true : value.trim().isEmpty();
+ }
+
+ /**
* Returns true if we are pooling statements.
*
* @return true if prepared and callable statements are pooled
@@ -1588,6 +1537,20 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
}
}
+ /**
+ * Logs the given throwable.
+ * @param message TODO
+ * @param throwable the throwable.
+ *
+ * @since 2.7.0
+ */
+ protected void log(String message, Throwable throwable) {
+ if (logWriter != null) {
+ logWriter.println(message);
+ throwable.printStackTrace(logWriter);
+ }
+ }
+
@Override
public void postDeregister() {
// NO-OP
@@ -1622,8 +1585,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
/**
* Removes a custom connection property.
*
- * @param name
- * Name of the custom connection property to remove
+ * @param name Name of the custom connection property to remove
* @see #addConnectionProperty(String, String)
*/
public void removeConnectionProperty(final String name) {
@@ -1633,8 +1595,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
/**
* Sets the print writer to be used by this configuration to log
information on abandoned objects.
*
- * @param logWriter
- * The new log writer
+ * @param logWriter The new log writer
*/
public void setAbandonedLogWriter(final PrintWriter logWriter) {
if (abandonedConfig == null) {
@@ -1652,9 +1613,8 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* the connection pool should record a stack trace every time a method is
called on a pooled connection and retain
* the most recent stack trace to aid debugging of abandoned connections.
*
- * @param usageTracking
- * A value of <code>true</code> will enable the recording of a
stack trace on every use of a pooled
- * connection
+ * @param usageTracking A value of <code>true</code> will enable the
recording of a stack trace on every use of a
+ * pooled connection
*/
public void setAbandonedUsageTracking(final boolean usageTracking) {
if (abandonedConfig == null) {
@@ -1678,8 +1638,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* setLoginTimeout, getLoginTimeout, getLogWriter.</code>
* </p>
*
- * @param allow
- * Access to the underlying connection is granted when true.
+ * @param allow Access to the underlying connection is granted when true.
*/
public synchronized void setAccessToUnderlyingConnectionAllowed(final
boolean allow) {
this.accessToUnderlyingConnectionAllowed = allow;
@@ -1690,25 +1649,40 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* and configured with {@link Connection#setAutoCommit(boolean)
Connection.setAutoCommit(true)} if the auto commit
* setting is {@code false} when the connection is returned. It is
<code>true</code> by default.
*
- * @param autoCommitOnReturn
- * Whether or not connections being returned to the pool will
be checked and configured with auto-commit.
+ * @param autoCommitOnReturn Whether or not connections being returned to
the pool will be checked and configured
+ * with auto-commit.
* @since 2.6.0
*/
public void setAutoCommitOnReturn(final boolean autoCommitOnReturn) {
this.autoCommitOnReturn = autoCommitOnReturn;
}
+ // ----------------------------------------------------- DataSource Methods
+
/**
* Sets the state caching flag.
*
- * @param cacheState
- * The new value for the state caching flag
+ * @param cacheState The new value for the state caching flag
*/
public void setCacheState(final boolean cacheState) {
this.cacheState = cacheState;
}
/**
+ * 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;
+ }
+ }
+
+ /**
* Sets the list of SQL statements to be executed when a physical
connection is first created.
* <p>
* Note: this method currently has no effect once the pool has been
initialized. The pool is initialized the first
@@ -1716,14 +1690,13 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* setLoginTimeout, getLoginTimeout, getLogWriter.</code>
* </p>
*
- * @param connectionInitSqls
- * Collection of SQL statements to execute on connection
creation
+ * @param connectionInitSqls Collection of SQL statements to execute on
connection creation
*/
public void setConnectionInitSqls(final Collection<String>
connectionInitSqls) {
if (connectionInitSqls != null && connectionInitSqls.size() > 0) {
ArrayList<String> newVal = null;
for (final String s : connectionInitSqls) {
- if (s != null && s.trim().length() > 0) {
+ if (!isEmpty(s)) {
if (newVal == null) {
newVal = new ArrayList<>();
}
@@ -1736,8 +1709,6 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
}
}
- // ----------------------------------------------------- DataSource Methods
-
/**
* Sets the connection properties passed to driver.connect(...).
* <p>
@@ -1747,8 +1718,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* NOTE - The "user" and "password" properties will be added explicitly,
so they do not need to be included here.
* </p>
*
- * @param connectionProperties
- * the connection properties used to create new connections
+ * @param connectionProperties the connection properties used to create
new connections
*/
public void setConnectionProperties(final String connectionProperties) {
Objects.requireNonNull(connectionProperties, "connectionProperties is
null");
@@ -1762,7 +1732,8 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
final String value = entry.substring(index + 1);
properties.setProperty(name, value);
} else {
- // no value is empty string which is how
java.util.Properties works
+ // no value is empty string which is how
+ // java.util.Properties works
properties.setProperty(entry, "");
}
}
@@ -1780,8 +1751,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* setLoginTimeout, getLoginTimeout, getLogWriter.</code>
* </p>
*
- * @param defaultAutoCommit
- * default auto-commit value
+ * @param defaultAutoCommit default auto-commit value
*/
public void setDefaultAutoCommit(final Boolean defaultAutoCommit) {
this.defaultAutoCommit = defaultAutoCommit;
@@ -1797,14 +1767,13 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* setLoginTimeout, getLoginTimeout, getLogWriter.</code>
* </p>
*
- * @param defaultCatalog
- * the default catalog
+ * @param defaultCatalog the default catalog
*/
public void setDefaultCatalog(final String defaultCatalog) {
- if (defaultCatalog != null && defaultCatalog.trim().length() > 0) {
- this.defaultCatalog = defaultCatalog;
- } else {
+ if (isEmpty(defaultCatalog)) {
this.defaultCatalog = null;
+ } else {
+ this.defaultCatalog = defaultCatalog;
}
}
@@ -1812,8 +1781,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* Sets the default query timeout that will be used for {@link
java.sql.Statement Statement}s created from this
* connection. <code>null</code> means that the driver default will be
used.
*
- * @param defaultQueryTimeoutSeconds
- * The default query timeout in seconds.
+ * @param defaultQueryTimeoutSeconds The default query timeout in seconds.
*/
public void setDefaultQueryTimeout(final Integer
defaultQueryTimeoutSeconds) {
this.defaultQueryTimeoutSeconds = defaultQueryTimeoutSeconds;
@@ -1829,8 +1797,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* setLoginTimeout, getLoginTimeout, getLogWriter.</code>
* </p>
*
- * @param defaultReadOnly
- * default read-only value
+ * @param defaultReadOnly default read-only value
*/
public void setDefaultReadOnly(final Boolean defaultReadOnly) {
this.defaultReadOnly = defaultReadOnly;
@@ -1846,15 +1813,14 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* setLoginTimeout, getLoginTimeout, getLogWriter.</code>
* </p>
*
- * @param defaultSchema
- * the default catalog
+ * @param defaultSchema the default catalog
* @since 2.5.0
*/
public void setDefaultSchema(final String defaultSchema) {
- if (defaultSchema != null && defaultSchema.trim().length() > 0) {
- this.defaultSchema = defaultSchema;
- } else {
+ if (isEmpty(defaultSchema)) {
this.defaultSchema = null;
+ } else {
+ this.defaultSchema = defaultSchema;
}
}
@@ -1868,8 +1834,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* setLoginTimeout, getLoginTimeout, getLogWriter.</code>
* </p>
*
- * @param defaultTransactionIsolation
- * the default transaction isolation state
+ * @param defaultTransactionIsolation the default transaction isolation
state
* @see Connection#getTransactionIsolation
*/
public void setDefaultTransactionIsolation(final int
defaultTransactionIsolation) {
@@ -1894,15 +1859,14 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* setLoginTimeout, getLoginTimeout, getLogWriter}.
* </p>
*
- * @param disconnectionSqlCodes
- * SQL_STATE codes considered to signal fatal conditions
+ * @param disconnectionSqlCodes SQL_STATE codes considered to signal fatal
conditions
* @since 2.1
*/
public void setDisconnectionSqlCodes(final Collection<String>
disconnectionSqlCodes) {
if (disconnectionSqlCodes != null && disconnectionSqlCodes.size() > 0)
{
HashSet<String> newVal = null;
for (final String s : disconnectionSqlCodes) {
- if (s != null && s.trim().length() > 0) {
+ if (!isEmpty(s)) {
if (newVal == null) {
newVal = new HashSet<>();
}
@@ -1923,8 +1887,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* setLoginTimeout, getLoginTimeout, getLogWriter.</code>
* </p>
*
- * @param driver
- * The JDBC Driver instance to use for this pool.
+ * @param driver The JDBC Driver instance to use for this pool.
*/
public synchronized void setDriver(final Driver driver) {
this.driver = driver;
@@ -1940,8 +1903,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* setLoginTimeout, getLoginTimeout, getLogWriter.</code>
* </p>
*
- * @param driverClassLoader
- * the class loader with which to load the JDBC driver
+ * @param driverClassLoader the class loader with which to load the JDBC
driver
*/
public synchronized void setDriverClassLoader(final ClassLoader
driverClassLoader) {
this.driverClassLoader = driverClassLoader;
@@ -1957,14 +1919,13 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* setLoginTimeout, getLoginTimeout, getLogWriter.</code>
* </p>
*
- * @param driverClassName
- * the class name of the JDBC driver
+ * @param driverClassName the class name of the JDBC driver
*/
public synchronized void setDriverClassName(final String driverClassName) {
- if (driverClassName != null && driverClassName.trim().length() > 0) {
- this.driverClassName = driverClassName;
- } else {
+ if (isEmpty(driverClassName)) {
this.driverClassName = null;
+ } else {
+ this.driverClassName = driverClassName;
}
}
@@ -1973,8 +1934,8 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* and configured with {@link Connection#setAutoCommit(boolean)
Connection.setAutoCommit(true)} if the auto commit
* setting is {@code false} when the connection is returned. It is
<code>true</code> by default.
*
- * @param autoCommitOnReturn
- * Whether or not connections being returned to the pool will
be checked and configured with auto-commit.
+ * @param autoCommitOnReturn Whether or not connections being returned to
the pool will be checked and configured
+ * with auto-commit.
* @deprecated Use {@link #setAutoCommitOnReturn(boolean)}.
*/
@Deprecated
@@ -1985,8 +1946,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
/**
* Sets the EvictionPolicy implementation to use with this connection pool.
*
- * @param evictionPolicyClassName
- * The fully qualified class name of the EvictionPolicy
implementation
+ * @param evictionPolicyClassName The fully qualified class name of the
EvictionPolicy implementation
*/
public synchronized void setEvictionPolicyClassName(final String
evictionPolicyClassName) {
if (connectionPool != null) {
@@ -1997,8 +1957,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
/**
* @see #getFastFailValidation()
- * @param fastFailValidation
- * true means connections created by this factory will fast
fail validation
+ * @param fastFailValidation true means connections created by this
factory will fast fail validation
* @since 2.1
*/
public void setFastFailValidation(final boolean fastFailValidation) {
@@ -2015,8 +1974,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* setLoginTimeout, getLoginTimeout, getLogWriter.</code>
* </p>
*
- * @param initialSize
- * the number of connections created when the pool is
initialized
+ * @param initialSize the number of connections created when the pool is
initialized
*/
public synchronized void setInitialSize(final int initialSize) {
this.initialSize = initialSize;
@@ -2028,8 +1986,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* this DataSource with JMX and this name is valid this name will be used
in preference to any specified by the
* other component.
*
- * @param jmxName
- * The JMX name that has been requested for this DataSource
+ * @param jmxName The JMX name that has been requested for this DataSource
*/
public void setJmxName(final String jmxName) {
this.jmxName = jmxName;
@@ -2038,8 +1995,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
/**
* Sets the LIFO property. True means the pool behaves as a LIFO queue;
false means FIFO.
*
- * @param lifo
- * the new value for the LIFO property
+ * @param lifo the new value for the LIFO property
*/
public synchronized void setLifo(final boolean lifo) {
this.lifo = lifo;
@@ -2049,8 +2005,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
}
/**
- * @param logAbandoned
- * new logAbandoned property value
+ * @param logAbandoned new logAbandoned property value
*/
public void setLogAbandoned(final boolean logAbandoned) {
if (abandonedConfig == null) {
@@ -2068,9 +2023,8 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* not log messages are generated when the pool closes connections due to
maximum lifetime exceeded. Set this
* property to false to suppress log messages when connections expire.
*
- * @param logExpiredConnections
- * Whether or not log messages are generated when the pool
closes connections due to maximum lifetime
- * exceeded.
+ * @param logExpiredConnections Whether or not log messages are generated
when the pool closes connections due to
+ * maximum lifetime exceeded.
*/
public void setLogExpiredConnections(final boolean logExpiredConnections) {
this.logExpiredConnections = logExpiredConnections;
@@ -2086,16 +2040,15 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* Calls {@link #createDataSource()}, so has the side effect of
initializing the connection pool.
* </p>
*
- * @param loginTimeout
- * The new login timeout, or zero for no timeout
- * @throws UnsupportedOperationException
- * If the DataSource implementation does not support the login
timeout feature.
- * @throws SQLException
- * if a database access error occurs
+ * @param loginTimeout The new login timeout, or zero for no timeout
+ * @throws UnsupportedOperationException If the DataSource implementation
does not support the login timeout
+ * feature.
+ * @throws SQLException if a database access error occurs
*/
@Override
public void setLoginTimeout(final int loginTimeout) 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");
}
@@ -2107,10 +2060,8 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* Calls {@link #createDataSource()}, so has the side effect of
initializing the connection pool.
* </p>
*
- * @param logWriter
- * The new log writer
- * @throws SQLException
- * if a database access error occurs
+ * @param logWriter The new log writer
+ * @throws SQLException if a database access error occurs
*/
@Override
public void setLogWriter(final PrintWriter logWriter) throws SQLException {
@@ -2129,8 +2080,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* setLoginTimeout, getLoginTimeout, getLogWriter.</code>
* </p>
*
- * @param maxConnLifetimeMillis
- * The maximum permitted lifetime of a connection in
milliseconds.
+ * @param maxConnLifetimeMillis The maximum permitted lifetime of a
connection in milliseconds.
*/
public void setMaxConnLifetimeMillis(final long maxConnLifetimeMillis) {
this.maxConnLifetimeMillis = maxConnLifetimeMillis;
@@ -2141,8 +2091,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* return to the pool.
*
* @see #getMaxIdle()
- * @param maxIdle
- * the new value for maxIdle
+ * @param maxIdle the new value for maxIdle
*/
public synchronized void setMaxIdle(final int maxIdle) {
this.maxIdle = maxIdle;
@@ -2161,8 +2110,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* setLoginTimeout, getLoginTimeout, getLogWriter.</code>
* </p>
*
- * @param maxOpenStatements
- * the new maximum number of prepared statements
+ * @param maxOpenStatements the new maximum number of prepared statements
*/
public synchronized void setMaxOpenPreparedStatements(final int
maxOpenStatements) {
this.maxOpenPreparedStatements = maxOpenStatements;
@@ -2172,8 +2120,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* Sets the maximum total number of idle and borrows connections that can
be active at the same time. Use a negative
* value for no limit.
*
- * @param maxTotal
- * the new value for maxTotal
+ * @param maxTotal the new value for maxTotal
* @see #getMaxTotal()
*/
public synchronized void setMaxTotal(final int maxTotal) {
@@ -2186,8 +2133,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
/**
* Sets the MaxWaitMillis property. Use -1 to make the pool wait
indefinitely.
*
- * @param maxWaitMillis
- * the new value for MaxWaitMillis
+ * @param maxWaitMillis the new value for MaxWaitMillis
* @see #getMaxWaitMillis()
*/
public synchronized void setMaxWaitMillis(final long maxWaitMillis) {
@@ -2200,8 +2146,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
/**
* Sets the {@link #minEvictableIdleTimeMillis} property.
*
- * @param minEvictableIdleTimeMillis
- * the minimum amount of time an object may sit idle in the pool
+ * @param minEvictableIdleTimeMillis the minimum amount of time an object
may sit idle in the pool
* @see #minEvictableIdleTimeMillis
*/
public synchronized void setMinEvictableIdleTimeMillis(final long
minEvictableIdleTimeMillis) {
@@ -2211,13 +2156,14 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
}
}
+ // ------------------------------------------------------ Protected Methods
+
/**
* Sets the minimum number of idle connections in the pool. The pool
attempts to ensure that minIdle connections are
* available when the idle object evictor runs. The value of this property
has no effect unless
* {@link #timeBetweenEvictionRunsMillis} has a positive value.
*
- * @param minIdle
- * the new value for minIdle
+ * @param minIdle the new value for minIdle
* @see GenericObjectPool#setMinIdle(int)
*/
public synchronized void setMinIdle(final int minIdle) {
@@ -2230,8 +2176,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
/**
* Sets the value of the {@link #numTestsPerEvictionRun} property.
*
- * @param numTestsPerEvictionRun
- * the new {@link #numTestsPerEvictionRun} value
+ * @param numTestsPerEvictionRun the new {@link #numTestsPerEvictionRun}
value
* @see #numTestsPerEvictionRun
*/
public synchronized void setNumTestsPerEvictionRun(final int
numTestsPerEvictionRun) {
@@ -2241,8 +2186,6 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
}
}
- // ------------------------------------------------------ Protected Methods
-
/**
* <p>
* Sets the {@link #password}.
@@ -2253,8 +2196,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* setLoginTimeout, getLoginTimeout, getLogWriter.</code>
* </p>
*
- * @param password
- * new value for the password
+ * @param password new value for the password
*/
public void setPassword(final String password) {
this.password = password;
@@ -2270,16 +2212,15 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* setLoginTimeout, getLoginTimeout, getLogWriter.</code>
* </p>
*
- * @param poolingStatements
- * pooling on or off
+ * @param poolingStatements pooling on or off
*/
public synchronized void setPoolPreparedStatements(final boolean
poolingStatements) {
this.poolPreparedStatements = poolingStatements;
}
/**
- * @param removeAbandonedOnBorrow
- * true means abandoned connections may be removed when
connections are borrowed from the pool.
+ * @param removeAbandonedOnBorrow true means abandoned connections may be
removed when connections are borrowed from
+ * the pool.
* @see #getRemoveAbandonedOnBorrow()
*/
public void setRemoveAbandonedOnBorrow(final boolean
removeAbandonedOnBorrow) {
@@ -2294,8 +2235,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
}
/**
- * @param removeAbandonedOnMaintenance
- * true means abandoned connections may be removed on pool
maintenance.
+ * @param removeAbandonedOnMaintenance true means abandoned connections
may be removed on pool maintenance.
* @see #getRemoveAbandonedOnMaintenance()
*/
public void setRemoveAbandonedOnMaintenance(final boolean
removeAbandonedOnMaintenance) {
@@ -2319,8 +2259,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* {@link #getRemoveAbandonedOnMaintenance()} are false.
* </p>
*
- * @param removeAbandonedTimeout
- * new abandoned timeout in seconds
+ * @param removeAbandonedTimeout new abandoned timeout in seconds
* @see #getRemoveAbandonedTimeout()
* @see #getRemoveAbandonedOnBorrow()
* @see #getRemoveAbandonedOnMaintenance()
@@ -2340,8 +2279,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* Sets the flag that controls if a connection will be rolled back when it
is returned to the pool if auto commit is
* not enabled and the connection is not read only.
*
- * @param rollbackOnReturn
- * whether a connection will be rolled back when it is returned
to the pool.
+ * @param rollbackOnReturn whether a connection will be rolled back when
it is returned to the pool.
*/
public void setRollbackOnReturn(final boolean rollbackOnReturn) {
this.rollbackOnReturn = rollbackOnReturn;
@@ -2351,9 +2289,9 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* Sets the minimum amount of time a connection may sit idle in the pool
before it is eligible for eviction by the
* idle object evictor, with the extra condition that at least "minIdle"
connections remain in the pool.
*
- * @param softMinEvictableIdleTimeMillis
- * minimum amount of time a connection may sit idle in the pool
before it is eligible for eviction,
- * assuming there are minIdle idle connections in the pool.
+ * @param softMinEvictableIdleTimeMillis minimum amount of time a
connection may sit idle in the pool before it is
+ * eligible for eviction, assuming
there are minIdle idle connections in the
+ * pool.
* @see #getSoftMinEvictableIdleTimeMillis
*/
public synchronized void setSoftMinEvictableIdleTimeMillis(final long
softMinEvictableIdleTimeMillis) {
@@ -2367,8 +2305,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* Sets the {@link #testOnBorrow} property. This property determines
whether or not the pool will validate objects
* before they are borrowed from the pool.
*
- * @param testOnBorrow
- * new value for testOnBorrow property
+ * @param testOnBorrow new value for testOnBorrow property
*/
public synchronized void setTestOnBorrow(final boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
@@ -2381,8 +2318,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* Sets the {@link #testOnCreate} property. This property determines
whether or not the pool will validate objects
* immediately after they are created by the pool
*
- * @param testOnCreate
- * new value for testOnCreate property
+ * @param testOnCreate new value for testOnCreate property
*/
public synchronized void setTestOnCreate(final boolean testOnCreate) {
this.testOnCreate = testOnCreate;
@@ -2395,8 +2331,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* Sets the <code>testOnReturn</code> property. This property determines
whether or not the pool will validate
* objects before they are returned to the pool.
*
- * @param testOnReturn
- * new value for testOnReturn property
+ * @param testOnReturn new value for testOnReturn property
*/
public synchronized void setTestOnReturn(final boolean testOnReturn) {
this.testOnReturn = testOnReturn;
@@ -2409,8 +2344,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* Sets the <code>testWhileIdle</code> property. This property determines
whether or not the idle object evictor
* will validate connections.
*
- * @param testWhileIdle
- * new value for testWhileIdle property
+ * @param testWhileIdle new value for testWhileIdle property
*/
public synchronized void setTestWhileIdle(final boolean testWhileIdle) {
this.testWhileIdle = testWhileIdle;
@@ -2422,8 +2356,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
/**
* Sets the {@link #timeBetweenEvictionRunsMillis} property.
*
- * @param timeBetweenEvictionRunsMillis
- * the new time between evictor runs
+ * @param timeBetweenEvictionRunsMillis the new time between evictor runs
* @see #timeBetweenEvictionRunsMillis
*/
public synchronized void setTimeBetweenEvictionRunsMillis(final long
timeBetweenEvictionRunsMillis) {
@@ -2443,8 +2376,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* setLoginTimeout, getLoginTimeout, getLogWriter.</code>
* </p>
*
- * @param url
- * the new value for the JDBC connection url
+ * @param url the new value for the JDBC connection url
*/
public synchronized void setUrl(final String url) {
this.url = url;
@@ -2460,8 +2392,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* setLoginTimeout, getLoginTimeout, getLogWriter.</code>
* </p>
*
- * @param userName
- * the new value for the JDBC connection user name
+ * @param userName the new value for the JDBC connection user name
*/
public void setUsername(final String userName) {
this.userName = userName;
@@ -2477,14 +2408,13 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* setLoginTimeout, getLoginTimeout, getLogWriter.</code>
* </p>
*
- * @param validationQuery
- * the new value for the validation query
+ * @param validationQuery the new value for the validation query
*/
public void setValidationQuery(final String validationQuery) {
- if (validationQuery != null && validationQuery.trim().length() > 0) {
- this.validationQuery = validationQuery;
- } else {
+ if (isEmpty(validationQuery)) {
this.validationQuery = null;
+ } else {
+ this.validationQuery = validationQuery;
}
}
@@ -2497,8 +2427,7 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
* setLoginTimeout, getLoginTimeout, getLogWriter.</code>
* </p>
*
- * @param validationQueryTimeoutSeconds
- * new validation query timeout value in seconds
+ * @param validationQueryTimeoutSeconds new validation query timeout value
in seconds
*/
public void setValidationQueryTimeout(final int
validationQueryTimeoutSeconds) {
this.validationQueryTimeoutSeconds = validationQueryTimeoutSeconds;
@@ -2527,4 +2456,5 @@ public class BasicDataSource implements DataSource,
BasicDataSourceMXBean, MBean
config.setJmxNameBase(base.toString());
config.setJmxNamePrefix(Constants.JMX_CONNECTION_POOL_PREFIX);
}
+
}
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceFactory.java
b/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceFactory.java
index eff9a7c..158b944 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceFactory.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/BasicDataSourceFactory.java
@@ -87,6 +87,7 @@ public class BasicDataSourceFactory implements ObjectFactory {
private static final String PROP_VALIDATION_QUERY = "validationQuery";
private static final String PROP_VALIDATION_QUERY_TIMEOUT =
"validationQueryTimeout";
private static final String PROP_JMX_NAME = "jmxName";
+ private static final String PROP_CONNECTION_FACTORY_CLASS_NAME =
"connectionFactoryClassName";
/**
* The property name for connectionInitSqls. The associated value String
must be of the form [query;]*
@@ -141,7 +142,8 @@ public class BasicDataSourceFactory implements
ObjectFactory {
PROP_REMOVE_ABANDONED_TIMEOUT, PROP_LOG_ABANDONED,
PROP_ABANDONED_USAGE_TRACKING, PROP_POOL_PREPARED_STATEMENTS,
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 };
+ PROP_DEFAULT_QUERY_TIMEOUT, PROP_FAST_FAIL_VALIDATION,
PROP_DISCONNECTION_SQL_CODES, PROP_JMX_NAME,
+ PROP_CONNECTION_FACTORY_CLASS_NAME };
/**
* Obsolete properties from DBCP 1.x. with warning strings suggesting new
properties. LinkedHashMap will guarantee
@@ -548,6 +550,11 @@ public class BasicDataSourceFactory implements
ObjectFactory {
dataSource.setDisconnectionSqlCodes(parseList(value, ','));
}
+ value = properties.getProperty(PROP_CONNECTION_FACTORY_CLASS_NAME);
+ if (value != null) {
+ dataSource.setConnectionFactoryClassName(value);
+ }
+
// DBCP-215
// Trick to make sure that initialSize connections are created
if (dataSource.getInitialSize() > 0) {
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/ConnectionFactoryFactory.java
b/java/org/apache/tomcat/dbcp/dbcp2/ConnectionFactoryFactory.java
new file mode 100644
index 0000000..708ee3a
--- /dev/null
+++ b/java/org/apache/tomcat/dbcp/dbcp2/ConnectionFactoryFactory.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tomcat.dbcp.dbcp2;
+
+import java.sql.Driver;
+import java.sql.SQLException;
+import java.util.Properties;
+
+/*
+ * Creates {@link ConnectionFactory} instances.
+ *
+ * @since 2.7.0
+ */
+class ConnectionFactoryFactory {
+
+ /**
+ * Creates a new {@link DriverConnectionFactory} allowing for an override
through
+ * {@link BasicDataSource#getDriverClassName()}.
+ *
+ * @param basicDataSource Configures creation.
+ * @param driver The JDBC driver.
+ * @return a new {@link DriverConnectionFactory} allowing for a {@link
BasicDataSource#getDriverClassName()}
+ * override.
+ * @throws SQLException Thrown when instantiation fails.
+ */
+ static ConnectionFactory createConnectionFactory(final BasicDataSource
basicDataSource, final Driver driver)
+ throws SQLException {
+ final Properties connectionProperties =
basicDataSource.getConnectionProperties();
+ final String url = basicDataSource.getUrl();
+ // Set up the driver connection factory we will use
+ final String user = basicDataSource.getUsername();
+ if (user != null) {
+ connectionProperties.put("user", user);
+ } else {
+ basicDataSource.log("DBCP DataSource configured without a
'username'");
+ }
+
+ final String pwd = basicDataSource.getPassword();
+ if (pwd != null) {
+ connectionProperties.put("password", pwd);
+ } else {
+ basicDataSource.log("DBCP DataSource configured without a
'password'");
+ }
+ final String connectionFactoryClassName =
basicDataSource.getConnectionFactoryClassName();
+ if (connectionFactoryClassName != null) {
+ try {
+ final Class<?> connectionFactoryFromCCL =
Class.forName(connectionFactoryClassName);
+ return (ConnectionFactory) connectionFactoryFromCCL
+ .getConstructor(Driver.class, String.class,
Properties.class)
+ .newInstance(driver, url, connectionProperties);
+ } catch (final Exception t) {
+ final String message = "Cannot load ConnectionFactory
implementation '" + connectionFactoryClassName
+ + "'";
+ basicDataSource.log(message, t);
+ throw new SQLException(message, t);
+ }
+ }
+ // Defaults to DriverConnectionFactory
+ return new DriverConnectionFactory(driver, url, connectionProperties);
+ }
+
+}
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingConnection.java
b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingConnection.java
index 5869a36..21d77eb 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingConnection.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingConnection.java
@@ -34,6 +34,7 @@ import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
@@ -87,19 +88,20 @@ public class DelegatingConnection<C extends Connection>
extends AbandonedTrace i
/**
* Returns a string representation of the metadata associated with the
innermost delegate connection.
*/
+ @SuppressWarnings("resource")
@Override
public synchronized String toString() {
- String s = null;
+ String str = null;
- final Connection c = this.getInnermostDelegateInternal();
- if (c != null) {
+ final Connection conn = this.getInnermostDelegateInternal();
+ if (conn != null) {
try {
- if (c.isClosed()) {
- s = "connection is closed";
+ if (conn.isClosed()) {
+ str = "connection is closed";
} else {
final StringBuffer sb = new StringBuffer();
sb.append(hashCode());
- final DatabaseMetaData meta = c.getMetaData();
+ final DatabaseMetaData meta = conn.getMetaData();
if (meta != null) {
sb.append(", URL=");
sb.append(meta.getURL());
@@ -107,19 +109,14 @@ public class DelegatingConnection<C extends Connection>
extends AbandonedTrace i
sb.append(meta.getUserName());
sb.append(", ");
sb.append(meta.getDriverName());
- s = sb.toString();
+ str = sb.toString();
}
}
} catch (final SQLException ex) {
// Ignore
}
}
-
- if (s == null) {
- s = super.toString();
- }
-
- return s;
+ return str != null ? str : super.toString();
}
/**
@@ -142,6 +139,7 @@ public class DelegatingConnection<C extends Connection>
extends AbandonedTrace i
* connection to compare innermost delegate with
* @return true if innermost delegate equals <code>c</code>
*/
+ @SuppressWarnings("resource")
public boolean innermostDelegateEquals(final Connection c) {
final Connection innerCon = getInnermostDelegateInternal();
if (innerCon == null) {
@@ -174,15 +172,16 @@ public class DelegatingConnection<C extends Connection>
extends AbandonedTrace i
*
* @return innermost delegate.
*/
+ @SuppressWarnings("resource")
public final Connection getInnermostDelegateInternal() {
- Connection c = connection;
- while (c != null && c instanceof DelegatingConnection) {
- c = ((DelegatingConnection<?>) c).getDelegateInternal();
- if (this == c) {
+ Connection conn = connection;
+ while (conn != null && conn instanceof DelegatingConnection) {
+ conn = ((DelegatingConnection<?>) conn).getDelegateInternal();
+ if (this == conn) {
return null;
}
}
- return c;
+ return conn;
}
/**
@@ -251,6 +250,18 @@ public class DelegatingConnection<C extends Connection>
extends AbandonedTrace i
throw e;
}
+ /**
+ * Handles the given {@code SQLException}.
+ *
+ * @param <T> The throwable type.
+ * @param e The SQLException
+ * @return the given {@code SQLException}
+ * @since 2.7.0
+ */
+ protected <T extends Throwable> T handleExceptionNoThrow(final T e) {
+ return e;
+ }
+
private void initializeStatement(final DelegatingStatement ds) throws
SQLException {
if (defaultQueryTimeoutSeconds != null &&
defaultQueryTimeoutSeconds.intValue() != ds.getQueryTimeout()) {
ds.setQueryTimeout(defaultQueryTimeoutSeconds.intValue());
@@ -606,23 +617,35 @@ public class DelegatingConnection<C extends Connection>
extends AbandonedTrace i
}
protected void passivate() throws SQLException {
- // The JDBC spec requires that a Connection close any open
+ // The JDBC specification requires that a Connection close any open
// Statement's when it is closed.
// DBCP-288. Not all the traced objects will be statements
final List<AbandonedTrace> traces = getTrace();
- if (traces != null && traces.size() > 0) {
+ if (traces != null && traces.isEmpty()) {
+ final List<Exception> thrown = new ArrayList<>();
final Iterator<AbandonedTrace> traceIter = traces.iterator();
while (traceIter.hasNext()) {
final Object trace = traceIter.next();
if (trace instanceof Statement) {
- ((Statement) trace).close();
+ try {
+ ((Statement) trace).close();
+ } catch (Exception e) {
+ thrown.add(e);
+ }
} else if (trace instanceof ResultSet) {
// DBCP-265: Need to close the result sets that are
// generated via DatabaseMetaData
- ((ResultSet) trace).close();
+ try {
+ ((ResultSet) trace).close();
+ } catch (Exception e) {
+ thrown.add(e);
+ }
}
}
clearTrace();
+ if (!thrown.isEmpty()) {
+ throw new SQLExceptionList(thrown);
+ }
}
setLastUsed(0);
}
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingResultSet.java
b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingResultSet.java
index 256a29d..0f61d1f 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingResultSet.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingResultSet.java
@@ -186,11 +186,11 @@ public final class DelegatingResultSet extends
AbandonedTrace implements ResultS
public void close() throws SQLException {
try {
if (statement != null) {
- ((AbandonedTrace) statement).removeTrace(this);
+ removeThisTrace(statement);
statement = null;
}
if (connection != null) {
- ((AbandonedTrace) connection).removeTrace(this);
+ removeThisTrace(connection);
connection = null;
}
resultSet.close();
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingStatement.java
b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingStatement.java
index 44aa05d..d4f9355 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/DelegatingStatement.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/DelegatingStatement.java
@@ -21,6 +21,7 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -125,35 +126,53 @@ public class DelegatingStatement extends AbandonedTrace
implements Statement {
if (isClosed()) {
return;
}
+ final List<Exception> thrown = new ArrayList<>();
try {
- try {
- if (connection != null) {
- connection.removeTrace(this);
- connection = null;
- }
+ if (connection != null) {
+ connection.removeTrace(this);
+ connection = null;
+ }
- // The JDBC spec requires that a statement close any open
- // ResultSet's when it is closed.
- // FIXME The PreparedStatement we're wrapping should handle
this for us.
- // See bug 17301 for what could happen when ResultSets are
closed twice.
- final List<AbandonedTrace> resultSets = getTrace();
- if (resultSets != null) {
- final ResultSet[] set = resultSets.toArray(new
ResultSet[resultSets.size()]);
- for (final ResultSet element : set) {
- element.close();
+ // The JDBC spec requires that a statement close any open
+ // ResultSet's when it is closed.
+ // FIXME The PreparedStatement we're wrapping should handle this
for us.
+ // See bug 17301 for what could happen when ResultSets are closed
twice.
+ final List<AbandonedTrace> resultSetList = getTrace();
+ if (resultSetList != null) {
+ final int size = resultSetList.size();
+ final ResultSet[] resultSets = resultSetList.toArray(new
ResultSet[size]);
+ for (final ResultSet resultSet : resultSets) {
+ if (resultSet != null) {
+ try {
+ resultSet.close();
+ } catch (Exception e) {
+ if (connection != null) {
+ // Does not rethrow e.
+ connection.handleExceptionNoThrow(e);
+ }
+ thrown.add(e);
+ }
}
clearTrace();
}
-
if (statement != null) {
- statement.close();
+ try {
+ statement.close();
+ } catch (Exception e) {
+ if (connection != null) {
+ // Does not rethrow e.
+ connection.handleExceptionNoThrow(e);
+ }
+ thrown.add(e);
+ }
}
- } catch (final SQLException e) {
- handleException(e);
}
} finally {
closed = true;
statement = null;
+ if (!thrown.isEmpty()) {
+ throw new SQLExceptionList(thrown);
+ }
}
}
@@ -615,7 +634,7 @@ public class DelegatingStatement extends AbandonedTrace
implements Statement {
}
/*
- * Note was protected prior to JDBC 4
+ * Note: This method was protected prior to JDBC 4.
*/
@Override
public boolean isClosed() throws SQLException {
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/DriverConnectionFactory.java
b/java/org/apache/tomcat/dbcp/dbcp2/DriverConnectionFactory.java
index 7e26052..45444ec 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/DriverConnectionFactory.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/DriverConnectionFactory.java
@@ -29,7 +29,9 @@ import java.util.Properties;
public class DriverConnectionFactory implements ConnectionFactory {
private final String connectionString;
+
private final Driver driver;
+
private final Properties properties;
/**
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/DriverFactory.java
b/java/org/apache/tomcat/dbcp/dbcp2/DriverFactory.java
new file mode 100644
index 0000000..82af50d
--- /dev/null
+++ b/java/org/apache/tomcat/dbcp/dbcp2/DriverFactory.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tomcat.dbcp.dbcp2;
+
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+/*
+ * Creates {@link Driver} instances.
+ *
+ * @since 2.7.0
+ */
+class DriverFactory {
+
+ static Driver createDriver(final BasicDataSource basicDataSource) throws
SQLException {
+ // Load the JDBC driver class
+ Driver driverToUse = basicDataSource.getDriver();
+ String driverClassName = basicDataSource.getDriverClassName();
+ ClassLoader driverClassLoader = basicDataSource.getDriverClassLoader();
+ String url = basicDataSource.getUrl();
+
+ if (driverToUse == null) {
+ Class<?> driverFromCCL = null;
+ if (driverClassName != null) {
+ try {
+ try {
+ if (driverClassLoader == null) {
+ driverFromCCL = Class.forName(driverClassName);
+ } else {
+ driverFromCCL = Class.forName(driverClassName,
true, driverClassLoader);
+ }
+ } catch (final ClassNotFoundException cnfe) {
+ driverFromCCL =
Thread.currentThread().getContextClassLoader().loadClass(driverClassName);
+ }
+ } catch (final Exception t) {
+ final String message = "Cannot load JDBC driver class '" +
driverClassName + "'";
+ basicDataSource.log(message, t);
+ throw new SQLException(message, t);
+ }
+ }
+
+ try {
+ if (driverFromCCL == null) {
+ driverToUse = DriverManager.getDriver(url);
+ } else {
+ // Usage of DriverManager is not possible, as it does not
+ // respect the ContextClassLoader
+ // N.B. This cast may cause ClassCastException which is
+ // handled below
+ driverToUse = (Driver)
driverFromCCL.getConstructor().newInstance();
+ if (!driverToUse.acceptsURL(url)) {
+ throw new SQLException("No suitable driver", "08001");
+ }
+ }
+ } catch (final Exception t) {
+ final String message = "Cannot create JDBC driver of class '"
+ + (driverClassName != null ? driverClassName : "") +
"' for connect URL '" + url + "'";
+ basicDataSource.log(message, t);
+ throw new SQLException(message, t);
+ }
+ }
+ return driverToUse;
+ }
+
+}
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/Jdbc41Bridge.java
b/java/org/apache/tomcat/dbcp/dbcp2/Jdbc41Bridge.java
index b4ee5b9..eb0d09d 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/Jdbc41Bridge.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/Jdbc41Bridge.java
@@ -304,7 +304,7 @@ public class Jdbc41Bridge {
return (T) resultSet.getURL(columnLabel);
}
throw new SQLFeatureNotSupportedException(
- String.format("resultSet=%s, columnLabel=%,d, type=%s",
resultSet, columnLabel, type));
+ String.format("resultSet=%s, columnLabel=%s, type=%s",
resultSet, columnLabel, type));
}
}
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/PoolableCallableStatement.java
b/java/org/apache/tomcat/dbcp/dbcp2/PoolableCallableStatement.java
index 486da28..9c0be44 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/PoolableCallableStatement.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/PoolableCallableStatement.java
@@ -21,6 +21,7 @@ import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.util.ArrayList;
import java.util.List;
import org.apache.tomcat.dbcp.pool2.KeyedObjectPool;
@@ -67,9 +68,7 @@ public class PoolableCallableStatement extends
DelegatingCallableStatement {
// Remove from trace now because this statement will be
// added by the activate method.
- if (getConnectionInternal() != null) {
- getConnectionInternal().removeTrace(this);
- }
+ removeThisTrace(getConnectionInternal());
}
/**
@@ -115,21 +114,29 @@ public class PoolableCallableStatement extends
DelegatingCallableStatement {
@Override
public void passivate() throws SQLException {
setClosedInternal(true);
- if (getConnectionInternal() != null) {
- getConnectionInternal().removeTrace(this);
- }
+ removeThisTrace(getConnectionInternal());
// The JDBC spec requires that a statement close any open
// ResultSet's when it is closed.
// FIXME The PreparedStatement we're wrapping should handle this for
us.
// See DBCP-10 for what could happen when ResultSets are closed twice.
- final List<AbandonedTrace> resultSets = getTrace();
- if (resultSets != null) {
- final ResultSet[] set = resultSets.toArray(new
ResultSet[resultSets.size()]);
- for (final ResultSet element : set) {
- element.close();
+ final List<AbandonedTrace> resultSetList = getTrace();
+ if (resultSetList != null) {
+ final List<Exception> thrown = new ArrayList<>();
+ final ResultSet[] resultSets = resultSetList.toArray(new
ResultSet[resultSetList.size()]);
+ for (final ResultSet resultSet : resultSets) {
+ if (resultSet != null) {
+ try {
+ resultSet.close();
+ } catch (Exception e) {
+ thrown.add(e);
+ }
+ }
}
clearTrace();
+ if (!thrown.isEmpty()) {
+ throw new SQLExceptionList(thrown);
+ }
}
super.passivate();
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/PoolablePreparedStatement.java
b/java/org/apache/tomcat/dbcp/dbcp2/PoolablePreparedStatement.java
index 29136d0..d8e45c4 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/PoolablePreparedStatement.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/PoolablePreparedStatement.java
@@ -20,6 +20,7 @@ package org.apache.tomcat.dbcp.dbcp2;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.util.ArrayList;
import java.util.List;
import org.apache.tomcat.dbcp.pool2.KeyedObjectPool;
@@ -29,6 +30,7 @@ import org.apache.tomcat.dbcp.pool2.KeyedObjectPool;
* {@link PreparedStatement}s.
* <p>
* My {@link #close} method returns me to my containing pool. (See {@link
PoolingConnection}.)
+ * </p>
*
* @param <K>
* the key type
@@ -37,6 +39,7 @@ import org.apache.tomcat.dbcp.pool2.KeyedObjectPool;
* @since 2.0
*/
public class PoolablePreparedStatement<K> extends DelegatingPreparedStatement {
+
/**
* The {@link KeyedObjectPool} from which I was obtained.
*/
@@ -50,7 +53,7 @@ public class PoolablePreparedStatement<K> extends
DelegatingPreparedStatement {
private volatile boolean batchAdded = false;
/**
- * Constructor
+ * Constructor.
*
* @param stmt
* my underlying {@link PreparedStatement}
@@ -69,9 +72,7 @@ public class PoolablePreparedStatement<K> extends
DelegatingPreparedStatement {
// Remove from trace now because this statement will be
// added by the activate method.
- if (getConnectionInternal() != null) {
- getConnectionInternal().removeTrace(this);
- }
+ removeThisTrace(getConnectionInternal());
}
/**
@@ -128,21 +129,29 @@ public class PoolablePreparedStatement<K> extends
DelegatingPreparedStatement {
clearBatch();
}
setClosedInternal(true);
- if (getConnectionInternal() != null) {
- getConnectionInternal().removeTrace(this);
- }
+ removeThisTrace(getConnectionInternal());
// The JDBC spec requires that a statement closes any open
// ResultSet's when it is closed.
// FIXME The PreparedStatement we're wrapping should handle this for
us.
// See bug 17301 for what could happen when ResultSets are closed
twice.
- final List<AbandonedTrace> resultSets = getTrace();
- if (resultSets != null) {
- final ResultSet[] set = resultSets.toArray(new
ResultSet[resultSets.size()]);
- for (final ResultSet element : set) {
- element.close();
+ final List<AbandonedTrace> resultSetList = getTrace();
+ if (resultSetList != null) {
+ final List<Exception> thrown = new ArrayList<>();
+ final ResultSet[] resultSets = resultSetList.toArray(new
ResultSet[resultSetList.size()]);
+ for (final ResultSet resultSet : resultSets) {
+ if (resultSet != null) {
+ try {
+ resultSet.close();
+ } catch (Exception e) {
+ thrown.add(e);
+ }
+ }
}
clearTrace();
+ if (!thrown.isEmpty()) {
+ throw new SQLExceptionList(thrown);
+ }
}
super.passivate();
diff --git a/java/org/apache/tomcat/dbcp/dbcp2/SQLExceptionList.java
b/java/org/apache/tomcat/dbcp/dbcp2/SQLExceptionList.java
new file mode 100644
index 0000000..b740ba0
--- /dev/null
+++ b/java/org/apache/tomcat/dbcp/dbcp2/SQLExceptionList.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tomcat.dbcp.dbcp2;
+
+import java.sql.SQLException;
+import java.util.List;
+
+/**
+ * A SQLException based on a list of Throwable causes.
+ * <p>
+ * The first exception in the list is used as this exception's cause and is
accessible with the usual
+ * {@link #getCause()} while the complete list is accessible with {@link
#getCauseList()}.
+ * </p>
+ *
+ * @since 2.7.0
+ */
+public class SQLExceptionList extends SQLException {
+
+ private static final long serialVersionUID = 1L;
+ private final List<? extends Throwable> causeList;
+
+ /**
+ * Creates a new exception caused by a list of exceptions.
+ *
+ * @param causeList a list of cause exceptions.
+ */
+ public SQLExceptionList(List<? extends Throwable> causeList) {
+ super(String.format("%,d exceptions: %s",
Integer.valueOf(causeList.size()), causeList), causeList.get(0));
+ this.causeList = causeList;
+ }
+
+ public List<? extends Throwable> getCauseList() {
+ return causeList;
+ }
+
+}
diff --git
a/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java
b/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java
index fe0944f..27ad570 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/DriverAdapterCPDS.java
@@ -86,6 +86,11 @@ public class DriverAdapterCPDS implements
ConnectionPoolDataSource, Referenceabl
private static final String GET_CONNECTION_CALLED = "A PooledConnection
was already requested from this source, "
+ "further initialization is not allowed.";
+ static {
+ // Attempt to prevent deadlocks - see DBCP - 272
+ DriverManager.getDrivers();
+ }
+
/** Description */
private String description;
@@ -106,13 +111,13 @@ public class DriverAdapterCPDS implements
ConnectionPoolDataSource, Referenceabl
/** Log stream. NOT USED */
private transient PrintWriter logWriter;
-
// PreparedStatement pool properties
private boolean poolPreparedStatements;
private int maxIdle = 10;
private long timeBetweenEvictionRunsMillis =
BaseObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
private int numTestsPerEvictionRun = -1;
private int minEvictableIdleTimeMillis = -1;
+
private int maxPreparedStatements = -1;
/** Whether or not getConnection has been called */
@@ -121,11 +126,6 @@ public class DriverAdapterCPDS implements
ConnectionPoolDataSource, Referenceabl
/** Connection properties passed to JDBC Driver */
private Properties connectionProperties;
- static {
- // Attempt to prevent deadlocks - see DBCP - 272
- DriverManager.getDrivers();
- }
-
/**
* Controls access to the underlying connection
*/
@@ -138,6 +138,208 @@ public class DriverAdapterCPDS implements
ConnectionPoolDataSource, Referenceabl
}
/**
+ * Throws an IllegalStateException, if a PooledConnection has already been
requested.
+ */
+ private void assertInitializationAllowed() throws IllegalStateException {
+ if (getConnectionCalled) {
+ throw new IllegalStateException(GET_CONNECTION_CALLED);
+ }
+ }
+
+ private boolean getBooleanContentString(RefAddr ra) {
+ return Boolean.valueOf(getStringContent(ra)).booleanValue();
+ }
+
+ /**
+ * Gets the connection properties passed to the JDBC driver.
+ *
+ * @return the JDBC connection properties used when creating connections.
+ */
+ public Properties getConnectionProperties() {
+ return connectionProperties;
+ }
+
+ /**
+ * Gets the value of description. This property is here for use by the
code which will deploy this datasource. It is
+ * not used internally.
+ *
+ * @return value of description, may be null.
+ * @see #setDescription(String)
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * Gets the driver class name.
+ *
+ * @return value of driver.
+ */
+ public String getDriver() {
+ return driver;
+ }
+
+ private int getIntegerStringContent(final RefAddr ra) {
+ return Integer.parseInt(getStringContent(ra));
+ }
+
+ /**
+ * Gets the maximum time in seconds that this data source can wait while
attempting to connect to a database. NOT
+ * USED.
+ */
+ @Override
+ public int getLoginTimeout() {
+ return loginTimeout;
+ }
+
+ /**
+ * Gets the log writer for this data source. NOT USED.
+ */
+ @Override
+ public PrintWriter getLogWriter() {
+ return logWriter;
+ }
+
+ /**
+ * Gets the maximum number of statements that can remain idle in the pool,
without extra ones being released, or
+ * negative for no limit.
+ *
+ * @return the value of maxIdle
+ */
+ public int getMaxIdle() {
+ return this.maxIdle;
+ }
+
+ /**
+ * Gets the maximum number of prepared statements.
+ *
+ * @return maxPrepartedStatements value
+ */
+ public int getMaxPreparedStatements() {
+ return maxPreparedStatements;
+ }
+
+ /**
+ * Gets the minimum amount of time a statement may sit idle in the pool
before it is eligible for eviction by the
+ * idle object evictor (if any).
+ *
+ * @see #setMinEvictableIdleTimeMillis
+ * @see #setTimeBetweenEvictionRunsMillis
+ * @return the minimum amount of time a statement may sit idle in the pool.
+ */
+ public int getMinEvictableIdleTimeMillis() {
+ return minEvictableIdleTimeMillis;
+ }
+
+ /**
+ * Gets the number of statements to examine during each run of the idle
object evictor thread (if any.)
+ *
+ * @see #setNumTestsPerEvictionRun
+ * @see #setTimeBetweenEvictionRunsMillis
+ * @return the number of statements to examine during each run of the idle
object evictor thread (if any.)
+ */
+ public int getNumTestsPerEvictionRun() {
+ return numTestsPerEvictionRun;
+ }
+
+ /**
+ * Implements {@link ObjectFactory} to create an instance of this class
+ */
+ @Override
+ public Object getObjectInstance(final Object refObj, final Name name,
final Context context,
+ final Hashtable<?, ?> env) throws Exception {
+ // The spec says to return null if we can't create an instance
+ // of the reference
+ DriverAdapterCPDS cpds = null;
+ if (refObj instanceof Reference) {
+ final Reference ref = (Reference) refObj;
+ if (ref.getClassName().equals(getClass().getName())) {
+ RefAddr ra = ref.get("description");
+ if (isNotEmpty(ra)) {
+ setDescription(getStringContent(ra));
+ }
+
+ ra = ref.get("driver");
+ if (isNotEmpty(ra)) {
+ setDriver(getStringContent(ra));
+ }
+ ra = ref.get("url");
+ if (isNotEmpty(ra)) {
+ setUrl(getStringContent(ra));
+ }
+ ra = ref.get(KEY_USER);
+ if (isNotEmpty(ra)) {
+ setUser(getStringContent(ra));
+ }
+ ra = ref.get(KEY_PASSWORD);
+ if (isNotEmpty(ra)) {
+ setPassword(getStringContent(ra));
+ }
+
+ ra = ref.get("poolPreparedStatements");
+ if (isNotEmpty(ra)) {
+ setPoolPreparedStatements(getBooleanContentString(ra));
+ }
+ ra = ref.get("maxIdle");
+ if (isNotEmpty(ra)) {
+ setMaxIdle(getIntegerStringContent(ra));
+ }
+
+ ra = ref.get("timeBetweenEvictionRunsMillis");
+ if (isNotEmpty(ra)) {
+
setTimeBetweenEvictionRunsMillis(getIntegerStringContent(ra));
+ }
+
+ ra = ref.get("numTestsPerEvictionRun");
+ if (isNotEmpty(ra)) {
+ setNumTestsPerEvictionRun(getIntegerStringContent(ra));
+ }
+
+ ra = ref.get("minEvictableIdleTimeMillis");
+ if (isNotEmpty(ra)) {
+ setMinEvictableIdleTimeMillis(getIntegerStringContent(ra));
+ }
+ ra = ref.get("maxPreparedStatements");
+ if (isNotEmpty(ra)) {
+ setMaxPreparedStatements(getIntegerStringContent(ra));
+ }
+
+ ra = ref.get("accessToUnderlyingConnectionAllowed");
+ if (isNotEmpty(ra)) {
+
setAccessToUnderlyingConnectionAllowed(getBooleanContentString(ra));
+ }
+
+ cpds = this;
+ }
+ }
+ return cpds;
+ }
+
+ @Override
+ public Logger getParentLogger() throws SQLFeatureNotSupportedException {
+ throw new SQLFeatureNotSupportedException();
+ }
+
+ /**
+ * Gets the value of password for the default user.
+ *
+ * @return value of password.
+ */
+ public String getPassword() {
+ return Utils.toString(userPassword);
+ }
+
+ /**
+ * Gets the value of password for the default user.
+ *
+ * @return value of password.
+ * @since 2.4.0
+ */
+ public char[] getPasswordCharArray() {
+ return userPassword;
+ }
+
+ /**
* Attempts to establish a database connection using the default user and
password.
*/
@Override
@@ -146,7 +348,7 @@ public class DriverAdapterCPDS implements
ConnectionPoolDataSource, Referenceabl
}
/**
- * Attempt to establish a database connection.
+ * Attempts to establish a database connection.
*
* @param pooledUserName
* name to be used for the connection
@@ -208,16 +410,8 @@ public class DriverAdapterCPDS implements
ConnectionPoolDataSource, Referenceabl
return pooledConnection;
}
- @Override
- public Logger getParentLogger() throws SQLFeatureNotSupportedException {
- throw new SQLFeatureNotSupportedException();
- }
-
- // ----------------------------------------------------------------------
- // Referenceable implementation
-
/**
- * <CODE>Referenceable</CODE> implementation.
+ * Implements {@link Referenceable}.
*/
@Override
public Reference getReference() throws NamingException {
@@ -243,256 +437,110 @@ public class DriverAdapterCPDS implements
ConnectionPoolDataSource, Referenceabl
return ref;
}
- // ----------------------------------------------------------------------
- // ObjectFactory implementation
-
- /**
- * implements ObjectFactory to create an instance of this class
- */
- @Override
- public Object getObjectInstance(final Object refObj, final Name name,
final Context context,
- final Hashtable<?, ?> env) throws Exception {
- // The spec says to return null if we can't create an instance
- // of the reference
- DriverAdapterCPDS cpds = null;
- if (refObj instanceof Reference) {
- final Reference ref = (Reference) refObj;
- if (ref.getClassName().equals(getClass().getName())) {
- RefAddr ra = ref.get("description");
- if (ra != null && ra.getContent() != null) {
- setDescription(ra.getContent().toString());
- }
-
- ra = ref.get("driver");
- if (ra != null && ra.getContent() != null) {
- setDriver(ra.getContent().toString());
- }
- ra = ref.get("url");
- if (ra != null && ra.getContent() != null) {
- setUrl(ra.getContent().toString());
- }
- ra = ref.get(KEY_USER);
- if (ra != null && ra.getContent() != null) {
- setUser(ra.getContent().toString());
- }
- ra = ref.get(KEY_PASSWORD);
- if (ra != null && ra.getContent() != null) {
- setPassword(ra.getContent().toString());
- }
-
- ra = ref.get("poolPreparedStatements");
- if (ra != null && ra.getContent() != null) {
-
setPoolPreparedStatements(Boolean.valueOf(ra.getContent().toString()).booleanValue());
- }
- ra = ref.get("maxIdle");
- if (ra != null && ra.getContent() != null) {
- setMaxIdle(Integer.parseInt(ra.getContent().toString()));
- }
-
- ra = ref.get("timeBetweenEvictionRunsMillis");
- if (ra != null && ra.getContent() != null) {
-
setTimeBetweenEvictionRunsMillis(Integer.parseInt(ra.getContent().toString()));
- }
-
- ra = ref.get("numTestsPerEvictionRun");
- if (ra != null && ra.getContent() != null) {
-
setNumTestsPerEvictionRun(Integer.parseInt(ra.getContent().toString()));
- }
-
- ra = ref.get("minEvictableIdleTimeMillis");
- if (ra != null && ra.getContent() != null) {
-
setMinEvictableIdleTimeMillis(Integer.parseInt(ra.getContent().toString()));
- }
- ra = ref.get("maxPreparedStatements");
- if (ra != null && ra.getContent() != null) {
-
setMaxPreparedStatements(Integer.parseInt(ra.getContent().toString()));
- }
-
- ra = ref.get("accessToUnderlyingConnectionAllowed");
- if (ra != null && ra.getContent() != null) {
-
setAccessToUnderlyingConnectionAllowed(Boolean.valueOf(ra.getContent().toString()).booleanValue());
- }
-
- cpds = this;
- }
- }
- return cpds;
- }
-
- /**
- * Throws an IllegalStateException, if a PooledConnection has already been
requested.
- */
- private void assertInitializationAllowed() throws IllegalStateException {
- if (getConnectionCalled) {
- throw new IllegalStateException(GET_CONNECTION_CALLED);
- }
+ private String getStringContent(RefAddr ra) {
+ return ra.getContent().toString();
}
- // ----------------------------------------------------------------------
- // Properties
-
/**
- * Gets the connection properties passed to the JDBC driver.
- *
- * @return the JDBC connection properties used when creating connections.
- */
- public Properties getConnectionProperties() {
- return connectionProperties;
- }
-
- /**
- * <p>
- * Sets the connection properties passed to the JDBC driver.
- * </p>
- *
- * <p>
- * If <code>props</code> contains "user" and/or "password" properties, the
corresponding instance properties are
- * set. If these properties are not present, they are filled in using
{@link #getUser()}, {@link #getPassword()}
- * when {@link #getPooledConnection()} is called, or using the actual
parameters to the method call when
- * {@link #getPooledConnection(String, String)} is called. Calls to {@link
#setUser(String)} or
- * {@link #setPassword(String)} overwrite the values of these properties
if <code>connectionProperties</code> is not
- * null.
- * </p>
- *
- * @param props
- * Connection properties to use when creating new connections.
- * @throws IllegalStateException
- * if {@link #getPooledConnection()} has been called
- */
- public void setConnectionProperties(final Properties props) {
- assertInitializationAllowed();
- connectionProperties = props;
- if (connectionProperties != null) {
- if (connectionProperties.containsKey(KEY_USER)) {
- setUser(connectionProperties.getProperty(KEY_USER));
- }
- if (connectionProperties.containsKey(KEY_PASSWORD)) {
- setPassword(connectionProperties.getProperty(KEY_PASSWORD));
- }
- }
- }
-
- /**
- * Gets the value of description. This property is here for use by the
code which will deploy this datasource. It is
- * not used internally.
- *
- * @return value of description, may be null.
- * @see #setDescription(String)
- */
- public String getDescription() {
- return description;
- }
-
- /**
- * Sets the value of description. This property is here for use by the
code which will deploy this datasource. It is
- * not used internally.
- *
- * @param v
- * Value to assign to description.
- */
- public void setDescription(final String v) {
- this.description = v;
- }
-
- /**
- * Gets the value of password for the default user.
- *
- * @return value of password.
- * @since 2.4.0
- */
- public char[] getPasswordCharArray() {
- return userPassword;
- }
-
- /**
- * Gets the value of password for the default user.
+ * Gets the number of milliseconds to sleep between runs of the idle
object evictor thread. When non-positive, no
+ * idle object evictor thread will be run.
*
- * @return value of password.
+ * @return the value of the evictor thread timer
+ * @see #setTimeBetweenEvictionRunsMillis(long)
*/
- public String getPassword() {
- return Utils.toString(userPassword);
+ public long getTimeBetweenEvictionRunsMillis() {
+ return timeBetweenEvictionRunsMillis;
}
/**
- * Sets the value of password for the default user.
+ * Gets the value of url used to locate the database for this datasource.
*
- * @param userPassword
- * Value to assign to password.
- * @throws IllegalStateException
- * if {@link #getPooledConnection()} has been called
+ * @return value of url.
*/
- public void setPassword(final char[] userPassword) {
- assertInitializationAllowed();
- this.userPassword = Utils.clone(userPassword);
- update(connectionProperties, KEY_PASSWORD,
Utils.toString(this.userPassword));
+ public String getUrl() {
+ return url;
}
/**
- * Sets the value of password for the default user.
+ * Gets the value of default user (login or user name).
*
- * @param userPassword
- * Value to assign to password.
- * @throws IllegalStateException
- * if {@link #getPooledConnection()} has been called
+ * @return value of user.
*/
- public void setPassword(final String userPassword) {
- assertInitializationAllowed();
- this.userPassword = Utils.toCharArray(userPassword);
- update(connectionProperties, KEY_PASSWORD, userPassword);
+ public String getUser() {
+ return userName;
}
/**
- * Gets the value of url used to locate the database for this datasource.
+ * Returns the value of the accessToUnderlyingConnectionAllowed property.
*
- * @return value of url.
+ * @return true if access to the underlying is allowed, false otherwise.
*/
- public String getUrl() {
- return url;
+ public synchronized boolean isAccessToUnderlyingConnectionAllowed() {
+ return this.accessToUnderlyingConnectionAllowed;
+ }
+
+ private boolean isNotEmpty(RefAddr ra) {
+ return ra != null && ra.getContent() != null;
}
/**
- * Sets the value of URL string used to locate the database for this
datasource.
+ * Whether to toggle the pooling of <code>PreparedStatement</code>s
*
- * @param v
- * Value to assign to url.
- * @throws IllegalStateException
- * if {@link #getPooledConnection()} has been called
+ * @return value of poolPreparedStatements.
*/
- public void setUrl(final String v) {
- assertInitializationAllowed();
- this.url = v;
+ public boolean isPoolPreparedStatements() {
+ return poolPreparedStatements;
}
/**
- * Gets the value of default user (login or user name).
+ * Sets the value of the accessToUnderlyingConnectionAllowed property. It
controls if the PoolGuard allows access to
+ * the underlying connection. (Default: false)
*
- * @return value of user.
+ * @param allow
+ * Access to the underlying connection is granted when true.
*/
- public String getUser() {
- return userName;
+ public synchronized void setAccessToUnderlyingConnectionAllowed(final
boolean allow) {
+ this.accessToUnderlyingConnectionAllowed = allow;
}
/**
- * Sets the value of default user (login or user name).
+ * Sets the connection properties passed to the JDBC driver.
+ * <p>
+ * If <code>props</code> contains "user" and/or "password" properties, the
corresponding instance properties are
+ * set. If these properties are not present, they are filled in using
{@link #getUser()}, {@link #getPassword()}
+ * when {@link #getPooledConnection()} is called, or using the actual
parameters to the method call when
+ * {@link #getPooledConnection(String, String)} is called. Calls to {@link
#setUser(String)} or
+ * {@link #setPassword(String)} overwrite the values of these properties
if <code>connectionProperties</code> is not
+ * null.
+ * </p>
*
- * @param v
- * Value to assign to user.
+ * @param props
+ * Connection properties to use when creating new connections.
* @throws IllegalStateException
* if {@link #getPooledConnection()} has been called
*/
- public void setUser(final String v) {
+ public void setConnectionProperties(final Properties props) {
assertInitializationAllowed();
- this.userName = v;
- update(connectionProperties, KEY_USER, v);
+ connectionProperties = props;
+ if (connectionProperties != null) {
+ if (connectionProperties.containsKey(KEY_USER)) {
+ setUser(connectionProperties.getProperty(KEY_USER));
+ }
+ if (connectionProperties.containsKey(KEY_PASSWORD)) {
+ setPassword(connectionProperties.getProperty(KEY_PASSWORD));
+ }
+ }
}
/**
- * Gets the driver class name.
+ * Sets the value of description. This property is here for use by the
code which will deploy this datasource. It is
+ * not used internally.
*
- * @return value of driver.
+ * @param v
+ * Value to assign to description.
*/
- public String getDriver() {
- return driver;
+ public void setDescription(final String v) {
+ this.description = v;
}
/**
@@ -514,23 +562,6 @@ public class DriverAdapterCPDS implements
ConnectionPoolDataSource, Referenceabl
}
/**
- * Gets the maximum time in seconds that this data source can wait while
attempting to connect to a database. NOT
- * USED.
- */
- @Override
- public int getLoginTimeout() {
- return loginTimeout;
- }
-
- /**
- * Gets the log writer for this data source. NOT USED.
- */
- @Override
- public PrintWriter getLogWriter() {
- return logWriter;
- }
-
- /**
* Sets the maximum time in seconds that this data source will wait while
attempting to connect to a database. NOT
* USED.
*/
@@ -547,41 +578,6 @@ public class DriverAdapterCPDS implements
ConnectionPoolDataSource, Referenceabl
logWriter = out;
}
- // ------------------------------------------------------------------
- // PreparedStatement pool properties
-
- /**
- * Flag to toggle the pooling of <code>PreparedStatement</code>s
- *
- * @return value of poolPreparedStatements.
- */
- public boolean isPoolPreparedStatements() {
- return poolPreparedStatements;
- }
-
- /**
- * Flag to toggle the pooling of <code>PreparedStatement</code>s
- *
- * @param poolPreparedStatements
- * true to pool statements.
- * @throws IllegalStateException
- * if {@link #getPooledConnection()} has been called
- */
- public void setPoolPreparedStatements(final boolean
poolPreparedStatements) {
- assertInitializationAllowed();
- this.poolPreparedStatements = poolPreparedStatements;
- }
-
- /**
- * Gets the maximum number of statements that can remain idle in the pool,
without extra ones being released, or
- * negative for no limit.
- *
- * @return the value of maxIdle
- */
- public int getMaxIdle() {
- return this.maxIdle;
- }
-
/**
* Gets the maximum number of statements that can remain idle in the pool,
without extra ones being released, or
* negative for no limit.
@@ -597,41 +593,29 @@ public class DriverAdapterCPDS implements
ConnectionPoolDataSource, Referenceabl
}
/**
- * Gets the number of milliseconds to sleep between runs of the idle
object evictor thread. When non-positive, no
- * idle object evictor thread will be run.
+ * Sets the maximum number of prepared statements.
*
- * @return the value of the evictor thread timer
- * @see #setTimeBetweenEvictionRunsMillis(long)
+ * @param maxPreparedStatements
+ * the new maximum number of prepared statements
*/
- public long getTimeBetweenEvictionRunsMillis() {
- return timeBetweenEvictionRunsMillis;
+ public void setMaxPreparedStatements(final int maxPreparedStatements) {
+ this.maxPreparedStatements = maxPreparedStatements;
}
/**
- * Sets the number of milliseconds to sleep between runs of the idle
object evictor thread. When non-positive, no
- * idle object evictor thread will be run.
+ * Sets the minimum amount of time a statement may sit idle in the pool
before it is eligible for eviction by the
+ * idle object evictor (if any). When non-positive, no objects will be
evicted from the pool due to idle time alone.
*
- * @param timeBetweenEvictionRunsMillis
- * The number of milliseconds to sleep between runs of the idle
object evictor thread. When non-positive,
- * no idle object evictor thread will be run.
- * @see #getTimeBetweenEvictionRunsMillis()
+ * @param minEvictableIdleTimeMillis
+ * minimum time to set (in ms)
+ * @see #getMinEvictableIdleTimeMillis()
+ * @see #setTimeBetweenEvictionRunsMillis(long)
* @throws IllegalStateException
* if {@link #getPooledConnection()} has been called
*/
- public void setTimeBetweenEvictionRunsMillis(final long
timeBetweenEvictionRunsMillis) {
+ public void setMinEvictableIdleTimeMillis(final int
minEvictableIdleTimeMillis) {
assertInitializationAllowed();
- this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
- }
-
- /**
- * Gets the number of statements to examine during each run of the idle
object evictor thread (if any.)
- *
- * @see #setNumTestsPerEvictionRun
- * @see #setTimeBetweenEvictionRunsMillis
- * @return the number of statements to examine during each run of the idle
object evictor thread (if any.)
- */
- public int getNumTestsPerEvictionRun() {
- return numTestsPerEvictionRun;
+ this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
}
/**
@@ -655,80 +639,87 @@ public class DriverAdapterCPDS implements
ConnectionPoolDataSource, Referenceabl
}
/**
- * Gets the minimum amount of time a statement may sit idle in the pool
before it is eligible for eviction by the
- * idle object evictor (if any).
+ * Sets the value of password for the default user.
*
- * @see #setMinEvictableIdleTimeMillis
- * @see #setTimeBetweenEvictionRunsMillis
- * @return the minimum amount of time a statement may sit idle in the pool.
+ * @param userPassword
+ * Value to assign to password.
+ * @throws IllegalStateException
+ * if {@link #getPooledConnection()} has been called
*/
- public int getMinEvictableIdleTimeMillis() {
- return minEvictableIdleTimeMillis;
+ public void setPassword(final char[] userPassword) {
+ assertInitializationAllowed();
+ this.userPassword = Utils.clone(userPassword);
+ update(connectionProperties, KEY_PASSWORD,
Utils.toString(this.userPassword));
}
/**
- * Sets the minimum amount of time a statement may sit idle in the pool
before it is eligible for eviction by the
- * idle object evictor (if any). When non-positive, no objects will be
evicted from the pool due to idle time alone.
+ * Sets the value of password for the default user.
*
- * @param minEvictableIdleTimeMillis
- * minimum time to set (in ms)
- * @see #getMinEvictableIdleTimeMillis()
- * @see #setTimeBetweenEvictionRunsMillis(long)
+ * @param userPassword
+ * Value to assign to password.
* @throws IllegalStateException
* if {@link #getPooledConnection()} has been called
*/
- public void setMinEvictableIdleTimeMillis(final int
minEvictableIdleTimeMillis) {
+ public void setPassword(final String userPassword) {
assertInitializationAllowed();
- this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
+ this.userPassword = Utils.toCharArray(userPassword);
+ update(connectionProperties, KEY_PASSWORD, userPassword);
}
/**
- * Returns the value of the accessToUnderlyingConnectionAllowed property.
+ * Whether to toggle the pooling of <code>PreparedStatement</code>s
*
- * @return true if access to the underlying is allowed, false otherwise.
+ * @param poolPreparedStatements
+ * true to pool statements.
+ * @throws IllegalStateException
+ * if {@link #getPooledConnection()} has been called
*/
- public synchronized boolean isAccessToUnderlyingConnectionAllowed() {
- return this.accessToUnderlyingConnectionAllowed;
+ public void setPoolPreparedStatements(final boolean
poolPreparedStatements) {
+ assertInitializationAllowed();
+ this.poolPreparedStatements = poolPreparedStatements;
}
/**
- * Sets the value of the accessToUnderlyingConnectionAllowed property. It
controls if the PoolGuard allows access to
- * the underlying connection. (Default: false)
+ * Sets the number of milliseconds to sleep between runs of the idle
object evictor thread. When non-positive, no
+ * idle object evictor thread will be run.
*
- * @param allow
- * Access to the underlying connection is granted when true.
+ * @param timeBetweenEvictionRunsMillis
+ * The number of milliseconds to sleep between runs of the idle
object evictor thread. When non-positive,
+ * no idle object evictor thread will be run.
+ * @see #getTimeBetweenEvictionRunsMillis()
+ * @throws IllegalStateException
+ * if {@link #getPooledConnection()} has been called
*/
- public synchronized void setAccessToUnderlyingConnectionAllowed(final
boolean allow) {
- this.accessToUnderlyingConnectionAllowed = allow;
+ public void setTimeBetweenEvictionRunsMillis(final long
timeBetweenEvictionRunsMillis) {
+ assertInitializationAllowed();
+ this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
}
/**
- * Gets the maximum number of prepared statements.
+ * Sets the value of URL string used to locate the database for this
datasource.
*
- * @return maxPrepartedStatements value
+ * @param v
+ * Value to assign to url.
+ * @throws IllegalStateException
+ * if {@link #getPooledConnection()} has been called
*/
- public int getMaxPreparedStatements() {
- return maxPreparedStatements;
+ public void setUrl(final String v) {
+ assertInitializationAllowed();
+ this.url = v;
}
/**
- * Sets the maximum number of prepared statements.
+ * Sets the value of default user (login or user name).
*
- * @param maxPreparedStatements
- * the new maximum number of prepared statements
+ * @param v
+ * Value to assign to user.
+ * @throws IllegalStateException
+ * if {@link #getPooledConnection()} has been called
*/
- public void setMaxPreparedStatements(final int maxPreparedStatements) {
- this.maxPreparedStatements = maxPreparedStatements;
- }
-
- private void update(final Properties properties, final String key, final
String value) {
- if (properties != null) {
- if (value == null) {
- properties.remove(key);
- } else {
- properties.setProperty(key, value);
- }
- }
+ public void setUser(final String v) {
+ assertInitializationAllowed();
+ this.userName = v;
+ update(connectionProperties, KEY_USER, v);
}
/**
@@ -765,7 +756,7 @@ public class DriverAdapterCPDS implements
ConnectionPoolDataSource, Referenceabl
builder.append(", connectionProperties=");
Properties tmpProps = connectionProperties;
final String pwdKey = "password";
- if (connectionProperties.contains(pwdKey)) {
+ if (connectionProperties != null &&
connectionProperties.contains(pwdKey)) {
tmpProps = (Properties) connectionProperties.clone();
tmpProps.remove(pwdKey);
}
@@ -775,4 +766,14 @@ public class DriverAdapterCPDS implements
ConnectionPoolDataSource, Referenceabl
builder.append("]");
return builder.toString();
}
+
+ private void update(final Properties properties, final String key, final
String value) {
+ if (properties != null && key != null) {
+ if (value == null) {
+ properties.remove(key);
+ } else {
+ properties.setProperty(key, value);
+ }
+ }
+ }
}
diff --git
a/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PooledConnectionImpl.java
b/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PooledConnectionImpl.java
index 046ce99..6d2456b 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PooledConnectionImpl.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/cpdsadapter/PooledConnectionImpl.java
@@ -181,6 +181,10 @@ class PooledConnectionImpl
/**
* Creates a {@link PStmtKey} for the given arguments.
+ *
+ * @param sql
+ * The SQL statement.
+ * @return a {@link PStmtKey} for the given arguments.
*/
protected PStmtKey createKey(final String sql) {
return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(),
getSchemaOrNull());
@@ -188,6 +192,13 @@ class PooledConnectionImpl
/**
* Creates a {@link PStmtKey} for the given arguments.
+ *
+ * @param sql
+ * The SQL 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 a key to uniquely identify a prepared statement.
*/
protected PStmtKey createKey(final String sql, final int
autoGeneratedKeys) {
return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(),
getSchemaOrNull(), autoGeneratedKeys);
@@ -195,6 +206,13 @@ class PooledConnectionImpl
/**
* Creates a {@link PStmtKey} for the given arguments.
+ *
+ * @param sql
+ * The SQL statement.
+ * @param columnIndexes
+ * An array of column indexes indicating the columns that
should be returned from the inserted row or
+ * rows.
+ * @return a key to uniquely identify a prepared statement.
*/
protected PStmtKey createKey(final String sql, final int columnIndexes[]) {
return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(),
getSchemaOrNull(), columnIndexes);
@@ -202,6 +220,16 @@ class PooledConnectionImpl
/**
* Creates a {@link PStmtKey} for the given arguments.
+ *
+ * @param sql
+ * The SQL statement.
+ * @param resultSetType
+ * A result set type; one of
<code>ResultSet.TYPE_FORWARD_ONLY</code>,
+ * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
<code>ResultSet.TYPE_SCROLL_SENSITIVE</code>.
+ * @param resultSetConcurrency
+ * A concurrency type; one of
<code>ResultSet.CONCUR_READ_ONLY</code> or
+ * <code>ResultSet.CONCUR_UPDATABLE</code>.
+ * @return a key to uniquely identify a prepared statement.
*/
protected PStmtKey createKey(final String sql, final int resultSetType,
final int resultSetConcurrency) {
return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(),
getSchemaOrNull(), resultSetType,
@@ -210,6 +238,19 @@ class PooledConnectionImpl
/**
* Creates a {@link PStmtKey} for the given arguments.
+ *
+ * @param sql
+ * The SQL statement.
+ * @param resultSetType
+ * a result set type; one of
<code>ResultSet.TYPE_FORWARD_ONLY</code>,
+ * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
<code>ResultSet.TYPE_SCROLL_SENSITIVE</code>.
+ * @param resultSetConcurrency
+ * A concurrency type; one of
<code>ResultSet.CONCUR_READ_ONLY</code> or
+ * <code>ResultSet.CONCUR_UPDATABLE</code>
+ * @param resultSetHoldability
+ * One of the following <code>ResultSet</code> constants:
<code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code>
+ * or <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>.
+ * @return a key to uniquely identify a prepared statement.
*/
protected PStmtKey createKey(final String sql, final int resultSetType,
final int resultSetConcurrency,
final int resultSetHoldability) {
@@ -220,6 +261,20 @@ class PooledConnectionImpl
/**
* Creates a {@link PStmtKey} for the given arguments.
*
+ * @param sql
+ * The SQL statement.
+ * @param resultSetType
+ * a result set type; one of
<code>ResultSet.TYPE_FORWARD_ONLY</code>,
+ * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
<code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
+ * @param resultSetConcurrency
+ * A concurrency type; one of
<code>ResultSet.CONCUR_READ_ONLY</code> or
+ * <code>ResultSet.CONCUR_UPDATABLE</code>.
+ * @param resultSetHoldability
+ * One of the following <code>ResultSet</code> constants:
<code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code>
+ * or <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>.
+ * @param statementType
+ * The SQL statement type, prepared or callable.
+ * @return a key to uniquely identify a prepared statement.
* @since 2.4.0
*/
protected PStmtKey createKey(final String sql, final int resultSetType,
final int resultSetConcurrency,
@@ -231,6 +286,17 @@ class PooledConnectionImpl
/**
* Creates a {@link PStmtKey} for the given arguments.
*
+ * @param sql
+ * The SQL statement.
+ * @param resultSetType
+ * A result set type; one of
<code>ResultSet.TYPE_FORWARD_ONLY</code>,
+ * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
<code>ResultSet.TYPE_SCROLL_SENSITIVE</code>.
+ * @param resultSetConcurrency
+ * A concurrency type; one of
<code>ResultSet.CONCUR_READ_ONLY</code> or
+ * <code>ResultSet.CONCUR_UPDATABLE</code>.
+ * @param statementType
+ * The SQL statement type, prepared or callable.
+ * @return a key to uniquely identify a prepared statement.
* @since 2.4.0
*/
protected PStmtKey createKey(final String sql, final int resultSetType,
final int resultSetConcurrency,
@@ -241,6 +307,12 @@ class PooledConnectionImpl
/**
* Creates a {@link PStmtKey} for the given arguments.
+ *
+ * @param sql
+ * The SQL statement.
+ * @param statementType
+ * The SQL statement type, prepared or callable.
+ * @return a key to uniquely identify a prepared statement.
*/
protected PStmtKey createKey(final String sql, final StatementType
statementType) {
return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(),
getSchemaOrNull(), statementType);
@@ -248,6 +320,12 @@ class PooledConnectionImpl
/**
* Creates a {@link PStmtKey} for the given arguments.
+ *
+ * @param sql
+ * The SQL statement.
+ * @param columnNames
+ * An array of column names indicating the columns that should
be returned from the inserted row or rows.
+ * @return a key to uniquely identify a prepared statement.
*/
protected PStmtKey createKey(final String sql, final String columnNames[])
{
return new PStmtKey(normalizeSQL(sql), getCatalogOrNull(),
getSchemaOrNull(), columnNames);
@@ -361,6 +439,9 @@ class PooledConnectionImpl
/**
* Normalizes the given SQL statement, producing a canonical form that is
semantically equivalent to the original.
+ * @param sql
+ * The SQL statement.
+ * @return the normalized SQL statement.
*/
protected String normalizeSQL(final String sql) {
return sql.trim();
diff --git
a/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSource.java
b/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSource.java
index a0fe1b4..e50e34d 100644
--- a/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSource.java
+++ b/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSource.java
@@ -98,7 +98,7 @@ public abstract class InstanceKeyDataSource implements
DataSource, Referenceable
/** Description */
private String description;
- /** Environment that may be used to set up a jndi initial context. */
+ /** Environment that may be used to set up a JNDI initial context. */
private Properties jndiEnvironment;
/** Login TimeOut in seconds */
@@ -146,6 +146,8 @@ public abstract class InstanceKeyDataSource implements
DataSource, Referenceable
/**
* Throws an IllegalStateException, if a PooledConnection has already been
requested.
+ *
+ * @throws IllegalStateException Thrown if a PooledConnection has already
been requested.
*/
protected void assertInitializationAllowed() throws IllegalStateException {
if (getConnectionCalled) {
@@ -520,8 +522,8 @@ public abstract class InstanceKeyDataSource implements
DataSource, Referenceable
}
/**
- * Gets the value of connectionPoolDataSource. This method will return
null, if the backing datasource is being
- * accessed via jndi.
+ * Gets the value of connectionPoolDataSource. This method will return
null, if the backing data source is being
+ * accessed via JNDI.
*
* @return value of connectionPoolDataSource.
*/
@@ -530,8 +532,8 @@ public abstract class InstanceKeyDataSource implements
DataSource, Referenceable
}
/**
- * Sets the backend ConnectionPoolDataSource. This property should not be
set if using jndi to access the
- * datasource.
+ * Sets the backend ConnectionPoolDataSource. This property should not be
set if using JNDI to access the
+ * data source.
*
* @param v
* Value to assign to connectionPoolDataSource.
@@ -549,8 +551,8 @@ public abstract class InstanceKeyDataSource implements
DataSource, Referenceable
}
/**
- * Gets the name of the ConnectionPoolDataSource which backs this pool.
This name is used to look up the datasource
- * from a jndi service provider.
+ * Gets the name of the ConnectionPoolDataSource which backs this pool.
This name is used to look up the data source
+ * from a JNDI service provider.
*
* @return value of dataSourceName.
*/
@@ -559,8 +561,8 @@ public abstract class InstanceKeyDataSource implements
DataSource, Referenceable
}
/**
- * Sets the name of the ConnectionPoolDataSource which backs this pool.
This name is used to look up the datasource
- * from a jndi service provider.
+ * Sets the name of the ConnectionPoolDataSource which backs this pool.
This name is used to look up the data source
+ * from a JNDI service provider.
*
* @param v
* Value to assign to dataSourceName.
diff --git
a/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSourceFactory.java
b/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSourceFactory.java
index eb0c8a9..c471d53 100644
---
a/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSourceFactory.java
+++
b/java/org/apache/tomcat/dbcp/dbcp2/datasources/InstanceKeyDataSourceFactory.java
@@ -120,7 +120,7 @@ abstract class InstanceKeyDataSourceFactory implements
ObjectFactory {
if (isCorrectClass(ref.getClassName())) {
final RefAddr refAddr = ref.get("instanceKey");
if (refAddr != null && refAddr.getContent() != null) {
- // object was bound to jndi via Referenceable api.
+ // object was bound to JNDI via Referenceable API.
obj = instanceMap.get(refAddr.getContent());
} else {
// Tomcat JNDI creates a Reference out of server.xml
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 0591676..2393a89 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -221,6 +221,10 @@
Update the internal fork of Commons Pool2 to 796e32d (2018-08-01) to
pick up the changes Commons Pool2 2.7.0. (markt)
</update>
+ <update>
+ Update the internal fork of Commons DBCP2 to 87d9e3a (2018-08-01) to
+ pick up the changes Commons DBCP2 2.7.0 RC1. (markt)
+ </update>
</changelog>
</subsection>
</section>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]