http://git-wip-us.apache.org/repos/asf/commons-dbcp/blob/6c97f898/src/main/java/org/apache/commons/dbcp2/BasicDataSource.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/dbcp2/BasicDataSource.java 
b/src/main/java/org/apache/commons/dbcp2/BasicDataSource.java
index 84ce723..a944da3 100644
--- a/src/main/java/org/apache/commons/dbcp2/BasicDataSource.java
+++ b/src/main/java/org/apache/commons/dbcp2/BasicDataSource.java
@@ -63,8 +63,21 @@ import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
  */
 public class BasicDataSource implements DataSource, BasicDataSourceMXBean, 
MBeanRegistration, AutoCloseable {
 
+    /**
+     * @since 2.0
+     */
+    private class PaGetConnection implements 
PrivilegedExceptionAction<Connection> {
+
+        @Override
+        public Connection run() throws SQLException {
+            return createDataSource().getConnection();
+        }
+    }
+
     private static final Log log = LogFactory.getLog(BasicDataSource.class);
 
+    // ------------------------------------------------------------- Properties
+
     static {
         // Attempt to prevent deadlocks - see DBCP - 272
         DriverManager.getDrivers();
@@ -95,7 +108,22 @@ public class BasicDataSource implements DataSource, 
BasicDataSourceMXBean, MBean
         }
     }
 
-    // ------------------------------------------------------------- Properties
+    protected static void validateConnectionFactory(final 
PoolableConnectionFactory connectionFactory)
+            throws Exception {
+        PoolableConnection conn = null;
+        PooledObject<PoolableConnection> p = null;
+        try {
+            p = connectionFactory.makeObject();
+            conn = p.getObject();
+            connectionFactory.activateObject(p);
+            connectionFactory.validateConnection(conn);
+            connectionFactory.passivateObject(p);
+        } finally {
+            if (p != null) {
+                connectionFactory.destroyObject(p);
+            }
+        }
+    }
 
     /**
      * The default auto-commit state of connections created by this pool.
@@ -103,1293 +131,1227 @@ public class BasicDataSource implements DataSource, 
BasicDataSourceMXBean, MBean
     private volatile Boolean defaultAutoCommit;
 
     /**
-     * Returns the default auto-commit property.
-     *
-     * @return true if default auto-commit is enabled
+     * The default read-only state of connections created by this pool.
      */
-    @Override
-    public Boolean getDefaultAutoCommit() {
-        return defaultAutoCommit;
-    }
+    private transient Boolean defaultReadOnly;
 
     /**
-     * <p>
-     * Sets default auto-commit state of connections returned by this 
datasource.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been 
initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, 
setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param defaultAutoCommit
-     *            default auto-commit value
+     * The default TransactionIsolation state of connections created by this 
pool.
      */
-    public void setDefaultAutoCommit(final Boolean defaultAutoCommit) {
-        this.defaultAutoCommit = defaultAutoCommit;
-    }
+    private volatile int defaultTransactionIsolation = 
PoolableConnectionFactory.UNKNOWN_TRANSACTION_ISOLATION;
+
+    private Integer defaultQueryTimeoutSeconds;
 
     /**
-     * The default read-only state of connections created by this pool.
+     * The default "catalog" of connections created by this pool.
      */
-    private transient Boolean defaultReadOnly;
+    private volatile String defaultCatalog;
 
     /**
-     * Returns the default readOnly property.
-     *
-     * @return true if connections are readOnly by default
+     * The default "schema" of connections created by this pool.
      */
-    @Override
-    public Boolean getDefaultReadOnly() {
-        return defaultReadOnly;
-    }
+    private volatile String defaultSchema;
 
     /**
-     * <p>
-     * Sets defaultReadonly property.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been 
initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, 
setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param defaultReadOnly
-     *            default read-only value
+     * The property that controls if the pooled connections cache some state 
rather than query the database for current
+     * state to improve performance.
      */
-    public void setDefaultReadOnly(final Boolean defaultReadOnly) {
-        this.defaultReadOnly = defaultReadOnly;
-    }
+    private boolean cacheState = true;
 
     /**
-     * The default TransactionIsolation state of connections created by this 
pool.
+     * The instance of the JDBC Driver to use.
      */
-    private volatile int defaultTransactionIsolation = 
PoolableConnectionFactory.UNKNOWN_TRANSACTION_ISOLATION;
+    private Driver driver;
 
     /**
-     * Returns the default transaction isolation state of returned connections.
-     *
-     * @return the default value for transaction isolation state
-     * @see Connection#getTransactionIsolation
+     * The fully qualified Java class name of the JDBC driver to be used.
      */
-    @Override
-    public int getDefaultTransactionIsolation() {
-        return this.defaultTransactionIsolation;
-    }
+    private String driverClassName;
 
     /**
-     * <p>
-     * Sets the default transaction isolation state for returned connections.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been 
initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, 
setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param defaultTransactionIsolation
-     *            the default transaction isolation state
-     * @see Connection#getTransactionIsolation
+     * The class loader instance to use to load the JDBC driver. If not 
specified, {@link Class#forName(String)} is used
+     * to load the JDBC driver. If specified, {@link Class#forName(String, 
boolean, ClassLoader)} is used.
      */
-    public void setDefaultTransactionIsolation(final int 
defaultTransactionIsolation) {
-        this.defaultTransactionIsolation = defaultTransactionIsolation;
-    }
+    private ClassLoader driverClassLoader;
 
-    private Integer defaultQueryTimeoutSeconds;
+    /**
+     * True means that borrowObject returns the most recently used ("last in") 
connection in the pool (if there are idle
+     * connections available). False means that the pool behaves as a FIFO 
queue - connections are taken from the idle
+     * instance pool in the order that they are returned to the pool.
+     */
+    private boolean lifo = BaseObjectPoolConfig.DEFAULT_LIFO;
 
     /**
-     * Gets 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.
-     *
-     * @return The default query timeout in seconds.
+     * The maximum number of active connections that can be allocated from 
this pool at the same time, or negative for
+     * no limit.
      */
-    public Integer getDefaultQueryTimeout() {
-        return defaultQueryTimeoutSeconds;
-    }
+    private int maxTotal = GenericObjectPoolConfig.DEFAULT_MAX_TOTAL;
 
     /**
-     * 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.
+     * The maximum number of connections that can remain idle in the pool, 
without extra ones being destroyed, or
+     * negative for no limit. If maxIdle is set too low on heavily loaded 
systems it is possible you will see
+     * connections being closed and almost immediately new connections being 
opened. This is a result of the active
+     * threads momentarily closing connections faster than they are opening 
them, causing the number of idle connections
+     * to rise above maxIdle. The best value for maxIdle for heavily loaded 
system will vary but the default is a good
+     * starting point.
      */
-    public void setDefaultQueryTimeout(final Integer 
defaultQueryTimeoutSeconds) {
-        this.defaultQueryTimeoutSeconds = defaultQueryTimeoutSeconds;
-    }
+    private int maxIdle = GenericObjectPoolConfig.DEFAULT_MAX_IDLE;
 
     /**
-     * The default "catalog" of connections created by this pool.
+     * The minimum number of active connections that can remain idle in the 
pool, without extra ones being created when
+     * the evictor runs, or 0 to create none. 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.
      */
-    private volatile String defaultCatalog;
+    private int minIdle = GenericObjectPoolConfig.DEFAULT_MIN_IDLE;
 
     /**
-     * The default "schema" of connections created by this pool.
+     * The initial number of connections that are created when the pool is 
started.
      */
-    private volatile String defaultSchema;
+    private int initialSize = 0;
 
     /**
-     * Returns the default catalog.
-     *
-     * @return the default catalog
+     * The maximum number of milliseconds that the pool will wait (when there 
are no available connections) for a
+     * connection to be returned before throwing an exception, or <= 0 to wait 
indefinitely.
      */
-    @Override
-    public String getDefaultCatalog() {
-        return this.defaultCatalog;
-    }
+    private long maxWaitMillis = BaseObjectPoolConfig.DEFAULT_MAX_WAIT_MILLIS;
 
     /**
-     * Returns the default schema.
-     *
-     * @return the default schema.
-     * @since 2.5.0
+     * Prepared statement pooling for this pool. When this property is set to 
<code>true</code> both PreparedStatements
+     * and CallableStatements are pooled.
      */
-    @Override
-    public String getDefaultSchema() {
-        return this.defaultSchema;
-    }
+    private boolean poolPreparedStatements = false;
 
     /**
      * <p>
-     * Sets the default catalog.
+     * The maximum number of open statements that can be allocated from the 
statement pool at the same time, or negative
+     * for no limit. Since a connection usually only uses one or two 
statements at a time, this is mostly used to help
+     * detect resource leaks.
      * </p>
      * <p>
-     * Note: this method currently has no effect once the pool has been 
initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, 
setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * Note: As of version 1.3, CallableStatements (those produced by {@link 
Connection#prepareCall}) are pooled along
+     * with PreparedStatements (produced by {@link 
Connection#prepareStatement}) and
+     * <code>maxOpenPreparedStatements</code> limits the total number of 
prepared or callable statements that may be in
+     * use at a given time.
      * </p>
-     *
-     * @param defaultCatalog
-     *            the default catalog
      */
-    public void setDefaultCatalog(final String defaultCatalog) {
-        if (defaultCatalog != null && defaultCatalog.trim().length() > 0) {
-            this.defaultCatalog = defaultCatalog;
-        } else {
-            this.defaultCatalog = null;
-        }
-    }
+    private int maxOpenPreparedStatements = 
GenericKeyedObjectPoolConfig.DEFAULT_MAX_TOTAL;
 
     /**
-     * <p>
-     * Sets the default schema.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been 
initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, 
setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param defaultSchema
-     *            the default catalog
-     * @since 2.5.0
+     * The indication of whether objects will be validated as soon as they 
have been created by the pool. If the object
+     * fails to validate, the borrow operation that triggered the creation 
will fail.
      */
-    public void setDefaultSchema(final String defaultSchema) {
-        if (defaultSchema != null && defaultSchema.trim().length() > 0) {
-            this.defaultSchema = defaultSchema;
-        } else {
-            this.defaultSchema = null;
-        }
-    }
+    private boolean testOnCreate = false;
 
     /**
-     * The property that controls if the pooled connections cache some state 
rather than query the database for current
-     * state to improve performance.
+     * The indication of whether objects will be validated before being 
borrowed from the pool. If the object fails to
+     * validate, it will be dropped from the pool, and we will attempt to 
borrow another.
      */
-    private boolean cacheState = true;
+    private boolean testOnBorrow = true;
 
     /**
-     * Returns the state caching flag.
-     *
-     * @return the state caching flag
+     * The indication of whether objects will be validated before being 
returned to the pool.
      */
-    @Override
-    public boolean getCacheState() {
-        return cacheState;
-    }
+    private boolean testOnReturn = false;
 
     /**
-     * Sets the state caching flag.
-     *
-     * @param cacheState
-     *            The new value for the state caching flag
+     * 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.
      */
-    public void setCacheState(final boolean cacheState) {
-        this.cacheState = cacheState;
-    }
+    private long timeBetweenEvictionRunsMillis = 
BaseObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
 
     /**
-     * The instance of the JDBC Driver to use.
+     * The number of objects to examine during each run of the idle object 
evictor thread (if any).
      */
-    private Driver driver;
+    private int numTestsPerEvictionRun = 
BaseObjectPoolConfig.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
 
     /**
-     * Returns the JDBC Driver that has been configured for use by this pool.
-     * <p>
-     * Note: This getter only returns the last value set by a call to {@link 
#setDriver(Driver)}. It does not return any
-     * driver instance that may have been created from the value set via 
{@link #setDriverClassName(String)}.
-     * </p>
-     *
-     * @return the JDBC Driver that has been configured for use by this pool
+     * The minimum amount of time an object may sit idle in the pool before it 
is eligible for eviction by the idle
+     * object evictor (if any).
      */
-    public synchronized Driver getDriver() {
-        return driver;
-    }
+    private long minEvictableIdleTimeMillis = 
BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
 
     /**
-     * Sets the JDBC Driver instance to use for this pool.
-     * <p>
-     * Note: this method currently has no effect once the pool has been 
initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, 
setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param driver
-     *            The JDBC Driver instance to use for this pool.
+     * 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. Note that
+     * {@code minEvictableIdleTimeMillis} takes precedence over this 
parameter. See
+     * {@link #getSoftMinEvictableIdleTimeMillis()}.
      */
-    public synchronized void setDriver(final Driver driver) {
-        this.driver = driver;
-    }
+    private long softMinEvictableIdleTimeMillis = 
BaseObjectPoolConfig.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
+
+    private String evictionPolicyClassName = 
BaseObjectPoolConfig.DEFAULT_EVICTION_POLICY_CLASS_NAME;
 
     /**
-     * The fully qualified Java class name of the JDBC driver to be used.
+     * The indication of whether objects will be validated by the idle object 
evictor (if any). If an object fails to
+     * validate, it will be dropped from the pool.
      */
-    private String driverClassName;
+    private boolean testWhileIdle = false;
 
     /**
-     * Returns the JDBC driver class name.
-     * <p>
-     * Note: This getter only returns the last value set by a call to {@link 
#setDriverClassName(String)}. It does not
-     * return the class name of any driver that may have been set via {@link 
#setDriver(Driver)}.
-     * </p>
-     *
-     * @return the JDBC driver class name
+     * The connection password to be passed to our JDBC driver to establish a 
connection.
      */
-    @Override
-    public synchronized String getDriverClassName() {
-        return this.driverClassName;
-    }
+    private volatile String password;
 
     /**
-     * <p>
-     * Sets the JDBC driver class name.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been 
initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, 
setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param driverClassName
-     *            the class name of the JDBC driver
+     * The connection URL to be passed to our JDBC driver to establish a 
connection.
      */
-    public synchronized void setDriverClassName(final String driverClassName) {
-        if (driverClassName != null && driverClassName.trim().length() > 0) {
-            this.driverClassName = driverClassName;
-        } else {
-            this.driverClassName = null;
-        }
-    }
+    private String url;
 
     /**
-     * The class loader instance to use to load the JDBC driver. If not 
specified, {@link Class#forName(String)} is used
-     * to load the JDBC driver. If specified, {@link Class#forName(String, 
boolean, ClassLoader)} is used.
+     * The connection user name to be passed to our JDBC driver to establish a 
connection.
      */
-    private ClassLoader driverClassLoader;
+    private String userName;
 
     /**
-     * Returns the class loader specified for loading the JDBC driver. Returns 
<code>null</code> if no class loader has
-     * been explicitly specified.
-     * <p>
-     * Note: This getter only returns the last value set by a call to {@link 
#setDriverClassLoader(ClassLoader)}. It
-     * does not return the class loader of any driver that may have been set 
via {@link #setDriver(Driver)}.
-     * </p>
-     *
-     * @return The class loader specified for loading the JDBC driver.
+     * The SQL query that will be used to validate connections from this pool 
before returning them to the caller. If
+     * specified, this query <strong>MUST</strong> be an SQL SELECT statement 
that returns at least one row. If not
+     * specified, {@link Connection#isValid(int)} will be used to validate 
connections.
      */
-    public synchronized ClassLoader getDriverClassLoader() {
-        return this.driverClassLoader;
-    }
+    private volatile String validationQuery;
 
     /**
+     * Timeout in seconds before connection validation queries fail.
+     */
+    private volatile int validationQueryTimeoutSeconds = -1;
+
+    /**
+     * These SQL statements run once after a Connection is created.
      * <p>
-     * Sets the class loader to be used to load the JDBC driver.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been 
initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, 
setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * This property can be used for example to run ALTER SESSION SET 
NLS_SORT=XCYECH in an Oracle Database only once
+     * after connection creation.
      * </p>
-     *
-     * @param driverClassLoader
-     *            the class loader with which to load the JDBC driver
      */
-    public synchronized void setDriverClassLoader(final ClassLoader 
driverClassLoader) {
-        this.driverClassLoader = driverClassLoader;
-    }
+    private volatile List<String> connectionInitSqls;
 
     /**
-     * True means that borrowObject returns the most recently used ("last in") 
connection in the pool (if there are idle
-     * connections available). False means that the pool behaves as a FIFO 
queue - connections are taken from the idle
-     * instance pool in the order that they are returned to the pool.
+     * Controls access to the underlying connection.
      */
-    private boolean lifo = BaseObjectPoolConfig.DEFAULT_LIFO;
+    private boolean accessToUnderlyingConnectionAllowed = false;
+
+    private long maxConnLifetimeMillis = -1;
+
+    private boolean logExpiredConnections = true;
+
+    private String jmxName;
+
+    private boolean autoCommitOnReturn = true;
+
+    private boolean rollbackOnReturn = true;
+
+    private volatile Set<String> disconnectionSqlCodes;
+
+    private boolean fastFailValidation;
 
     /**
-     * Returns the LIFO property.
-     *
-     * @return true if connection pool behaves as a LIFO queue.
+     * The object pool that internally manages our connections.
      */
-    @Override
-    public synchronized boolean getLifo() {
-        return this.lifo;
-    }
+    private volatile GenericObjectPool<PoolableConnection> connectionPool;
 
     /**
-     * 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
+     * The connection properties that will be sent to our JDBC driver when 
establishing new connections.
+     * <strong>NOTE</strong> - The "user" and "password" properties will be 
passed explicitly, so they do not need to be
+     * included here.
      */
-    public synchronized void setLifo(final boolean lifo) {
-        this.lifo = lifo;
-        if (connectionPool != null) {
-            connectionPool.setLifo(lifo);
-        }
-    }
+    private Properties connectionProperties = new Properties();
 
     /**
-     * The maximum number of active connections that can be allocated from 
this pool at the same time, or negative for
-     * no limit.
+     * The data source we will use to manage connections. This object should 
be acquired <strong>ONLY</strong> by calls
+     * to the <code>createDataSource()</code> method.
      */
-    private int maxTotal = GenericObjectPoolConfig.DEFAULT_MAX_TOTAL;
+    private volatile DataSource dataSource;
 
     /**
-     * <p>
-     * Returns the maximum number of active connections that can be allocated 
at the same time.
-     * </p>
-     * <p>
-     * A negative number means that there is no limit.
-     * </p>
-     *
-     * @return the maximum number of active connections
+     * The PrintWriter to which log messages should be directed.
      */
-    @Override
-    public synchronized int getMaxTotal() {
-        return this.maxTotal;
-    }
+    private volatile PrintWriter logWriter = new PrintWriter(
+            new OutputStreamWriter(System.out, StandardCharsets.UTF_8));
+
+    private AbandonedConfig abandonedConfig;
+
+    private boolean closed;
 
     /**
-     * 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
-     * @see #getMaxTotal()
+     * Actual name under which this component has been registered.
      */
-    public synchronized void setMaxTotal(final int maxTotal) {
-        this.maxTotal = maxTotal;
-        if (connectionPool != null) {
-            connectionPool.setMaxTotal(maxTotal);
-        }
-    }
+    private ObjectNameWrapper registeredJmxObjectName;
 
     /**
-     * The maximum number of connections that can remain idle in the pool, 
without extra ones being destroyed, or
-     * negative for no limit. If maxIdle is set too low on heavily loaded 
systems it is possible you will see
-     * connections being closed and almost immediately new connections being 
opened. This is a result of the active
-     * threads momentarily closing connections faster than they are opening 
them, causing the number of idle connections
-     * to rise above maxIdle. The best value for maxIdle for heavily loaded 
system will vary but the default is a good
-     * starting point.
+     * Adds a custom connection property to the set that will be passed to our 
JDBC driver. This <strong>MUST</strong>
+     * 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
      */
-    private int maxIdle = GenericObjectPoolConfig.DEFAULT_MAX_IDLE;
+    public void addConnectionProperty(final String name, final String value) {
+        connectionProperties.put(name, value);
+    }
 
     /**
      * <p>
-     * Returns the maximum number of connections that can remain idle in the 
pool. Excess idle connections are destroyed
-     * on return to the pool.
+     * Closes and releases all idle connections that are currently stored in 
the connection pool associated with this
+     * data source.
      * </p>
      * <p>
-     * A negative value indicates that there is no limit
+     * Connections that are checked out to clients when this method is invoked 
are not affected. When client
+     * applications subsequently invoke {@link Connection#close()} to return 
these connections to the pool, the
+     * underlying JDBC connections are closed.
+     * </p>
+     * <p>
+     * Attempts to acquire connections using {@link #getConnection()} after 
this method has been invoked result in
+     * SQLExceptions.
+     * </p>
+     * <p>
+     * This method is idempotent - i.e., closing an already closed 
BasicDataSource has no effect and does not generate
+     * exceptions.
      * </p>
      *
-     * @return the maximum number of idle connections
+     * @throws SQLException
+     *             if an error occurs closing idle connections
      */
     @Override
-    public synchronized int getMaxIdle() {
-        return this.maxIdle;
+    public synchronized void close() throws SQLException {
+        if (registeredJmxObjectName != null) {
+            registeredJmxObjectName.unregisterMBean();
+            registeredJmxObjectName = null;
+        }
+        closed = true;
+        final GenericObjectPool<?> oldpool = connectionPool;
+        connectionPool = null;
+        dataSource = null;
+        try {
+            if (oldpool != null) {
+                oldpool.close();
+            }
+        } catch (final RuntimeException e) {
+            throw e;
+        } catch (final Exception e) {
+            throw new SQLException(Utils.getMessage("pool.close.fail"), e);
+        }
     }
 
     /**
-     * Sets the maximum number of connections that can remain idle in the 
pool. Excess idle connections are destroyed on
-     * return to the pool.
-     *
-     * @see #getMaxIdle()
-     * @param maxIdle
-     *            the new value for maxIdle
+     * Closes the connection pool, silently swallowing any exception that 
occurs.
      */
-    public synchronized void setMaxIdle(final int maxIdle) {
-        this.maxIdle = maxIdle;
-        if (connectionPool != null) {
-            connectionPool.setMaxIdle(maxIdle);
-        }
-    }
-
-    /**
-     * The minimum number of active connections that can remain idle in the 
pool, without extra ones being created when
-     * the evictor runs, or 0 to create none. 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.
-     */
-    private int minIdle = GenericObjectPoolConfig.DEFAULT_MIN_IDLE;
-
-    /**
-     * Returns 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.
-     *
-     * @return the minimum number of idle connections
-     * @see GenericObjectPool#getMinIdle()
-     */
-    @Override
-    public synchronized int getMinIdle() {
-        return this.minIdle;
-    }
-
-    /**
-     * 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
-     * @see GenericObjectPool#setMinIdle(int)
-     */
-    public synchronized void setMinIdle(final int minIdle) {
-        this.minIdle = minIdle;
-        if (connectionPool != null) {
-            connectionPool.setMinIdle(minIdle);
+    private void closeConnectionPool() {
+        final GenericObjectPool<?> oldPool = connectionPool;
+        connectionPool = null;
+        try {
+            if (oldPool != null) {
+                oldPool.close();
+            }
+        } catch (final Exception e) {
+            /* Ignore */
         }
     }
 
     /**
-     * The initial number of connections that are created when the pool is 
started.
-     */
-    private int initialSize = 0;
-
-    /**
-     * Returns the initial size of the connection pool.
+     * Creates a JDBC connection factory for this datasource. The JDBC driver 
is loaded using the following algorithm:
+     * <ol>
+     * <li>If a Driver instance has been specified via {@link 
#setDriver(Driver)} use it</li>
+     * <li>If no Driver instance was specified and {@link #driverClassName} is 
specified that class is loaded using the
+     * {@link ClassLoader} of this class or, if {@link #driverClassLoader} is 
set, {@link #driverClassName} is loaded
+     * with the specified {@link ClassLoader}.</li>
+     * <li>If {@link #driverClassName} is specified and the previous attempt 
fails, the class is loaded using the
+     * 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>
+     * This method exists so subclasses can replace the implementation class.
      *
-     * @return the number of connections created when the pool is initialized
-     */
-    @Override
-    public synchronized int getInitialSize() {
-        return this.initialSize;
-    }
-
-    /**
-     * <p>
-     * Sets the initial size of the connection pool.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been 
initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, 
setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
+     * @return A new connection factory.
      *
-     * @param initialSize
-     *            the number of connections created when the pool is 
initialized
+     * @throws SQLException
+     *            If the connection factort cannot be created
      */
-    public synchronized void setInitialSize(final int initialSize) {
-        this.initialSize = initialSize;
-    }
+    protected ConnectionFactory createConnectionFactory() throws SQLException {
+        // Load the JDBC driver class
+        Driver driverToUse = this.driver;
 
-    /**
-     * The maximum number of milliseconds that the pool will wait (when there 
are no available connections) for a
-     * connection to be returned before throwing an exception, or <= 0 to wait 
indefinitely.
-     */
-    private long maxWaitMillis = BaseObjectPoolConfig.DEFAULT_MAX_WAIT_MILLIS;
+        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);
+                }
+            }
 
-    /**
-     * Returns the maximum number of milliseconds that the pool will wait for 
a connection to be returned before
-     * throwing an exception. A value less than or equal to zero means the 
pool is set to wait indefinitely.
-     *
-     * @return the maxWaitMillis property value
-     */
-    @Override
-    public synchronized long getMaxWaitMillis() {
-        return this.maxWaitMillis;
-    }
+            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);
+            }
+        }
 
-    /**
-     * Sets the MaxWaitMillis property. Use -1 to make the pool wait 
indefinitely.
-     *
-     * @param maxWaitMillis
-     *            the new value for MaxWaitMillis
-     * @see #getMaxWaitMillis()
-     */
-    public synchronized void setMaxWaitMillis(final long maxWaitMillis) {
-        this.maxWaitMillis = maxWaitMillis;
-        if (connectionPool != null) {
-            connectionPool.setMaxWaitMillis(maxWaitMillis);
+        // 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'");
         }
-    }
 
-    /**
-     * Prepared statement pooling for this pool. When this property is set to 
<code>true</code> both PreparedStatements
-     * and CallableStatements are pooled.
-     */
-    private boolean poolPreparedStatements = false;
+        final String pwd = password;
+        if (pwd != null) {
+            connectionProperties.put("password", pwd);
+        } else {
+            log("DBCP DataSource configured without a 'password'");
+        }
 
-    /**
-     * Returns true if we are pooling statements.
-     *
-     * @return true if prepared and callable statements are pooled
-     */
-    @Override
-    public synchronized boolean isPoolPreparedStatements() {
-        return this.poolPreparedStatements;
+        final ConnectionFactory driverConnectionFactory = new 
DriverConnectionFactory(driverToUse, url,
+                connectionProperties);
+        return driverConnectionFactory;
     }
 
     /**
+     * Creates a connection pool for this datasource. This method only exists 
so subclasses can replace the
+     * implementation class.
      * <p>
-     * Sets whether to pool statements or not.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been 
initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, 
setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * This implementation configures all pool properties other than 
timeBetweenEvictionRunsMillis. Setting that
+     * property is deferred to {@link #startPoolMaintenance()}, since setting 
timeBetweenEvictionRunsMillis to a
+     * positive value causes {@link GenericObjectPool}'s eviction timer to be 
started.
      * </p>
      *
-     * @param poolingStatements
-     *            pooling on or off
+     * @param factory
+     *            The factory to use to create new connections for this pool.
      */
-    public synchronized void setPoolPreparedStatements(final boolean 
poolingStatements) {
-        this.poolPreparedStatements = poolingStatements;
+    protected void createConnectionPool(final PoolableConnectionFactory 
factory) {
+        // Create an object pool to contain our active connections
+        final GenericObjectPoolConfig<PoolableConnection> config = new 
GenericObjectPoolConfig<>();
+        updateJmxName(config);
+        // Disable JMX on the underlying pool if the DS is not registered:
+        config.setJmxEnabled(registeredJmxObjectName != null);
+        final GenericObjectPool<PoolableConnection> gop = 
createObjectPool(factory, config, abandonedConfig);
+        gop.setMaxTotal(maxTotal);
+        gop.setMaxIdle(maxIdle);
+        gop.setMinIdle(minIdle);
+        gop.setMaxWaitMillis(maxWaitMillis);
+        gop.setTestOnCreate(testOnCreate);
+        gop.setTestOnBorrow(testOnBorrow);
+        gop.setTestOnReturn(testOnReturn);
+        gop.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
+        gop.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
+        gop.setSoftMinEvictableIdleTimeMillis(softMinEvictableIdleTimeMillis);
+        gop.setTestWhileIdle(testWhileIdle);
+        gop.setLifo(lifo);
+        gop.setSwallowedExceptionListener(new SwallowedExceptionLogger(log, 
logExpiredConnections));
+        gop.setEvictionPolicyClassName(evictionPolicyClassName);
+        factory.setPool(gop);
+        connectionPool = gop;
     }
 
     /**
      * <p>
-     * The maximum number of open statements that can be allocated from the 
statement pool at the same time, or negative
-     * for no limit. Since a connection usually only uses one or two 
statements at a time, this is mostly used to help
-     * detect resource leaks.
-     * </p>
-     * <p>
-     * Note: As of version 1.3, CallableStatements (those produced by {@link 
Connection#prepareCall}) are pooled along
-     * with PreparedStatements (produced by {@link 
Connection#prepareStatement}) and
-     * <code>maxOpenPreparedStatements</code> limits the total number of 
prepared or callable statements that may be in
-     * use at a given time.
+     * Creates (if necessary) and return the internal data source we are using 
to manage our connections.
      * </p>
-     */
-    private int maxOpenPreparedStatements = 
GenericKeyedObjectPoolConfig.DEFAULT_MAX_TOTAL;
-
-    /**
-     * Gets the value of the <code>maxOpenPreparedStatements</code> property.
      *
-     * @return the maximum number of open statements
+     * @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.
      */
-    @Override
-    public synchronized int getMaxOpenPreparedStatements() {
-        return this.maxOpenPreparedStatements;
-    }
+    protected DataSource createDataSource() throws SQLException {
+        if (closed) {
+            throw new SQLException("Data source is closed");
+        }
 
-    /**
-     * <p>
-     * Sets the value of the <code>maxOpenPreparedStatements</code> property.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been 
initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, 
setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
-     *
-     * @param maxOpenStatements
-     *            the new maximum number of prepared statements
-     */
-    public synchronized void setMaxOpenPreparedStatements(final int 
maxOpenStatements) {
-        this.maxOpenPreparedStatements = maxOpenStatements;
-    }
+        // Return the pool if we have already created it
+        // This is double-checked locking. This is safe since dataSource is
+        // volatile and the code is targeted at Java 5 onwards.
+        if (dataSource != null) {
+            return dataSource;
+        }
+        synchronized (this) {
+            if (dataSource != null) {
+                return dataSource;
+            }
 
-    /**
-     * The indication of whether objects will be validated as soon as they 
have been created by the pool. If the object
-     * fails to validate, the borrow operation that triggered the creation 
will fail.
-     */
-    private boolean testOnCreate = false;
+            jmxRegister();
 
-    /**
-     * Returns the {@link #testOnCreate} property.
-     *
-     * @return true if objects are validated immediately after they are 
created by the pool
-     * @see #testOnCreate
-     */
-    @Override
-    public synchronized boolean getTestOnCreate() {
-        return this.testOnCreate;
-    }
+            // create factory which returns raw physical connections
+            final ConnectionFactory driverConnectionFactory = 
createConnectionFactory();
 
-    /**
-     * 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
-     */
-    public synchronized void setTestOnCreate(final boolean testOnCreate) {
-        this.testOnCreate = testOnCreate;
-        if (connectionPool != null) {
-            connectionPool.setTestOnCreate(testOnCreate);
+            // Set up the poolable connection factory
+            boolean success = false;
+            PoolableConnectionFactory poolableConnectionFactory;
+            try {
+                poolableConnectionFactory = 
createPoolableConnectionFactory(driverConnectionFactory);
+                
poolableConnectionFactory.setPoolStatements(poolPreparedStatements);
+                
poolableConnectionFactory.setMaxOpenPreparedStatements(maxOpenPreparedStatements);
+                success = true;
+            } catch (final SQLException se) {
+                throw se;
+            } catch (final RuntimeException rte) {
+                throw rte;
+            } catch (final Exception ex) {
+                throw new SQLException("Error creating connection factory", 
ex);
+            }
+
+            if (success) {
+                // create a pool for our connections
+                createConnectionPool(poolableConnectionFactory);
+            }
+
+            // Create the pooling data source to manage connections
+            DataSource newDataSource;
+            success = false;
+            try {
+                newDataSource = createDataSourceInstance();
+                newDataSource.setLogWriter(logWriter);
+                success = true;
+            } catch (final SQLException se) {
+                throw se;
+            } catch (final RuntimeException rte) {
+                throw rte;
+            } catch (final Exception ex) {
+                throw new SQLException("Error creating datasource", ex);
+            } finally {
+                if (!success) {
+                    closeConnectionPool();
+                }
+            }
+
+            // If initialSize > 0, preload the pool
+            try {
+                for (int i = 0; i < initialSize; i++) {
+                    connectionPool.addObject();
+                }
+            } catch (final Exception e) {
+                closeConnectionPool();
+                throw new SQLException("Error preloading the connection pool", 
e);
+            }
+
+            // If timeBetweenEvictionRunsMillis > 0, start the pool's evictor 
task
+            startPoolMaintenance();
+
+            dataSource = newDataSource;
+            return dataSource;
         }
     }
 
     /**
-     * The indication of whether objects will be validated before being 
borrowed from the pool. If the object fails to
-     * validate, it will be dropped from the pool, and we will attempt to 
borrow another.
-     */
-    private boolean testOnBorrow = true;
-
-    /**
-     * Returns the {@link #testOnBorrow} property.
+     * Creates the actual data source instance. This method only exists so 
that subclasses can replace the
+     * implementation class.
      *
-     * @return true if objects are validated before being borrowed from the 
pool
+     * @throws SQLException
+     *             if unable to create a datasource instance
      *
-     * @see #testOnBorrow
+     * @return A new DataSource instance
      */
-    @Override
-    public synchronized boolean getTestOnBorrow() {
-        return this.testOnBorrow;
+    protected DataSource createDataSourceInstance() throws SQLException {
+        final PoolingDataSource<PoolableConnection> pds = new 
PoolingDataSource<>(connectionPool);
+        
pds.setAccessToUnderlyingConnectionAllowed(isAccessToUnderlyingConnectionAllowed());
+        return pds;
     }
 
     /**
-     * Sets the {@link #testOnBorrow} property. This property determines 
whether or not the pool will validate objects
-     * before they are borrowed from the pool.
+     * Creates an object pool used to provide pooling support for {@link 
Connection JDBC connections}.
      *
-     * @param testOnBorrow
-     *            new value for testOnBorrow property
+     * @param factory
+     *            the object factory
+     * @param poolConfig
+     *            the object pool configuration
+     * @param abandonedConfig
+     *            the abandoned objects configuration
+     * @return a non-null instance
      */
-    public synchronized void setTestOnBorrow(final boolean testOnBorrow) {
-        this.testOnBorrow = testOnBorrow;
-        if (connectionPool != null) {
-            connectionPool.setTestOnBorrow(testOnBorrow);
+    protected GenericObjectPool<PoolableConnection> createObjectPool(final 
PoolableConnectionFactory factory,
+            final GenericObjectPoolConfig<PoolableConnection> poolConfig, 
final AbandonedConfig abandonedConfig) {
+        GenericObjectPool<PoolableConnection> gop;
+        if (abandonedConfig != null && 
(abandonedConfig.getRemoveAbandonedOnBorrow()
+                || abandonedConfig.getRemoveAbandonedOnMaintenance())) {
+            gop = new GenericObjectPool<>(factory, poolConfig, 
abandonedConfig);
+        } else {
+            gop = new GenericObjectPool<>(factory, poolConfig);
         }
+        return gop;
     }
 
     /**
-     * The indication of whether objects will be validated before being 
returned to the pool.
+     * 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
+     *
+     * @return A new PoolableConnectionFactory configured with the current 
configuration of this BasicDataSource
      */
-    private boolean testOnReturn = false;
+    protected PoolableConnectionFactory createPoolableConnectionFactory(final 
ConnectionFactory driverConnectionFactory)
+            throws SQLException {
+        PoolableConnectionFactory connectionFactory = null;
+        try {
+            connectionFactory = new 
PoolableConnectionFactory(driverConnectionFactory,
+                    ObjectNameWrapper.unwrap(registeredJmxObjectName));
+            connectionFactory.setValidationQuery(validationQuery);
+            
connectionFactory.setValidationQueryTimeout(validationQueryTimeoutSeconds);
+            connectionFactory.setConnectionInitSql(connectionInitSqls);
+            connectionFactory.setDefaultReadOnly(defaultReadOnly);
+            connectionFactory.setDefaultAutoCommit(defaultAutoCommit);
+            
connectionFactory.setDefaultTransactionIsolation(defaultTransactionIsolation);
+            connectionFactory.setDefaultCatalog(defaultCatalog);
+            connectionFactory.setDefaultSchema(defaultSchema);
+            connectionFactory.setCacheState(cacheState);
+            connectionFactory.setPoolStatements(poolPreparedStatements);
+            
connectionFactory.setMaxOpenPreparedStatements(maxOpenPreparedStatements);
+            connectionFactory.setMaxConnLifetimeMillis(maxConnLifetimeMillis);
+            connectionFactory.setRollbackOnReturn(getRollbackOnReturn());
+            connectionFactory.setAutoCommitOnReturn(getAutoCommitOnReturn());
+            connectionFactory.setDefaultQueryTimeout(getDefaultQueryTimeout());
+            connectionFactory.setFastFailValidation(fastFailValidation);
+            connectionFactory.setDisconnectionSqlCodes(disconnectionSqlCodes);
+            validateConnectionFactory(connectionFactory);
+        } catch (final RuntimeException e) {
+            throw e;
+        } catch (final Exception e) {
+            throw new SQLException("Cannot create PoolableConnectionFactory (" 
+ e.getMessage() + ")", e);
+        }
+        return connectionFactory;
+    }
 
     /**
-     * Returns the value of the {@link #testOnReturn} property.
+     * Gets the print writer used by this configuration to log information on 
abandoned objects.
      *
-     * @return true if objects are validated before being returned to the pool
-     * @see #testOnReturn
+     * @return The print writer used by this configuration to log information 
on abandoned objects.
      */
-    public synchronized boolean getTestOnReturn() {
-        return this.testOnReturn;
+    public PrintWriter getAbandonedLogWriter() {
+        if (abandonedConfig != null) {
+            return abandonedConfig.getLogWriter();
+        }
+        return null;
     }
 
     /**
-     * Sets the <code>testOnReturn</code> property. This property determines 
whether or not the pool will validate
-     * objects before they are returned to the pool.
+     * If the connection pool implements {@link 
org.apache.commons.pool2.UsageTracking UsageTracking}, should the
+     * connection pool 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 testOnReturn
-     *            new value for testOnReturn property
+     * @return <code>true</code> if usage tracking is enabled
      */
-    public synchronized void setTestOnReturn(final boolean testOnReturn) {
-        this.testOnReturn = testOnReturn;
-        if (connectionPool != null) {
-            connectionPool.setTestOnReturn(testOnReturn);
+    @Override
+    public boolean getAbandonedUsageTracking() {
+        if (abandonedConfig != null) {
+            return abandonedConfig.getUseUsageTracking();
         }
+        return false;
     }
 
     /**
-     * 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.
+     * Returns the value of the flag that controls whether or not connections 
being returned to the pool will be checked
+     * 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.
+     *
+     * @return Whether or not connections being returned to the pool will be 
checked and configured with auto-commit.
      */
-    private long timeBetweenEvictionRunsMillis = 
BaseObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
+    public boolean getAutoCommitOnReturn() {
+        return autoCommitOnReturn;
+    }
 
     /**
-     * Returns the value of the {@link #timeBetweenEvictionRunsMillis} 
property.
+     * Returns the state caching flag.
      *
-     * @return the time (in milliseconds) between evictor runs
-     * @see #timeBetweenEvictionRunsMillis
+     * @return the state caching flag
      */
     @Override
-    public synchronized long getTimeBetweenEvictionRunsMillis() {
-        return this.timeBetweenEvictionRunsMillis;
+    public boolean getCacheState() {
+        return cacheState;
     }
 
     /**
-     * Sets the {@link #timeBetweenEvictionRunsMillis} property.
+     * Creates (if necessary) and return a connection to the database.
      *
-     * @param timeBetweenEvictionRunsMillis
-     *            the new time between evictor runs
-     * @see #timeBetweenEvictionRunsMillis
+     * @throws SQLException
+     *             if a database access error occurs
+     * @return a database connection
      */
-    public synchronized void setTimeBetweenEvictionRunsMillis(final long 
timeBetweenEvictionRunsMillis) {
-        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
-        if (connectionPool != null) {
-            
connectionPool.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
+    @Override
+    public Connection getConnection() throws SQLException {
+        if (Utils.IS_SECURITY_ENABLED) {
+            final PrivilegedExceptionAction<Connection> action = new 
PaGetConnection();
+            try {
+                return AccessController.doPrivileged(action);
+            } catch (final PrivilegedActionException e) {
+                final Throwable cause = e.getCause();
+                if (cause instanceof SQLException) {
+                    throw (SQLException) cause;
+                }
+                throw new SQLException(e);
+            }
         }
+        return createDataSource().getConnection();
     }
 
     /**
-     * The number of objects to examine during each run of the idle object 
evictor thread (if any).
-     */
-    private int numTestsPerEvictionRun = 
BaseObjectPoolConfig.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
-
-    /**
-     * Returns the value of the {@link #numTestsPerEvictionRun} property.
+     * <strong>BasicDataSource does NOT support this method.</strong>
      *
-     * @return the number of objects to examine during idle object evictor runs
-     * @see #numTestsPerEvictionRun
+     * @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
+     * @return nothing - always throws UnsupportedOperationException
      */
     @Override
-    public synchronized int getNumTestsPerEvictionRun() {
-        return this.numTestsPerEvictionRun;
+    public Connection getConnection(final String user, final String pass) 
throws SQLException {
+        // This method isn't supported by the PoolingDataSource returned by 
the createDataSource
+        throw new UnsupportedOperationException("Not supported by 
BasicDataSource");
     }
 
     /**
-     * Sets the value of the {@link #numTestsPerEvictionRun} property.
+     * 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.
      *
-     * @param numTestsPerEvictionRun
-     *            the new {@link #numTestsPerEvictionRun} value
-     * @see #numTestsPerEvictionRun
+     * @return initialization SQL statements
      */
-    public synchronized void setNumTestsPerEvictionRun(final int 
numTestsPerEvictionRun) {
-        this.numTestsPerEvictionRun = numTestsPerEvictionRun;
-        if (connectionPool != null) {
-            connectionPool.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
+    public List<String> getConnectionInitSqls() {
+        final List<String> result = connectionInitSqls;
+        if (result == null) {
+            return Collections.emptyList();
         }
+        return result;
     }
 
     /**
-     * The minimum amount of time an object may sit idle in the pool before it 
is eligible for eviction by the idle
-     * object evictor (if any).
+     * Provides the same data as {@link #getConnectionInitSqls()} but in an 
array so it is accessible via JMX.
      */
-    private long minEvictableIdleTimeMillis = 
BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
+    @Override
+    public String[] getConnectionInitSqlsAsArray() {
+        final Collection<String> result = getConnectionInitSqls();
+        return result.toArray(new String[result.size()]);
+    }
+
+    protected GenericObjectPool<PoolableConnection> getConnectionPool() {
+        return connectionPool;
+    }
+
+    // For unit testing
+    Properties getConnectionProperties() {
+        return connectionProperties;
+    }
 
     /**
-     * Returns the {@link #minEvictableIdleTimeMillis} property.
+     * Returns the default auto-commit property.
      *
-     * @return the value of the {@link #minEvictableIdleTimeMillis} property
-     * @see #minEvictableIdleTimeMillis
+     * @return true if default auto-commit is enabled
      */
     @Override
-    public synchronized long getMinEvictableIdleTimeMillis() {
-        return this.minEvictableIdleTimeMillis;
+    public Boolean getDefaultAutoCommit() {
+        return defaultAutoCommit;
     }
 
     /**
-     * Sets the {@link #minEvictableIdleTimeMillis} property.
+     * Returns the default catalog.
      *
-     * @param minEvictableIdleTimeMillis
-     *            the minimum amount of time an object may sit idle in the pool
-     * @see #minEvictableIdleTimeMillis
+     * @return the default catalog
      */
-    public synchronized void setMinEvictableIdleTimeMillis(final long 
minEvictableIdleTimeMillis) {
-        this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
-        if (connectionPool != null) {
-            
connectionPool.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
-        }
+    @Override
+    public String getDefaultCatalog() {
+        return this.defaultCatalog;
     }
 
     /**
-     * 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. Note that
-     * {@code minEvictableIdleTimeMillis} takes precedence over this 
parameter. See
-     * {@link #getSoftMinEvictableIdleTimeMillis()}.
+     * Gets 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.
+     *
+     * @return The default query timeout in seconds.
      */
-    private long softMinEvictableIdleTimeMillis = 
BaseObjectPoolConfig.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
+    public Integer getDefaultQueryTimeout() {
+        return defaultQueryTimeoutSeconds;
+    }
 
     /**
-     * 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.
+     * Returns the default readOnly property.
      *
-     * @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
+     * @return true if connections are readOnly by default
      */
-    public synchronized void setSoftMinEvictableIdleTimeMillis(final long 
softMinEvictableIdleTimeMillis) {
-        this.softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;
-        if (connectionPool != null) {
-            
connectionPool.setSoftMinEvictableIdleTimeMillis(softMinEvictableIdleTimeMillis);
-        }
+    @Override
+    public Boolean getDefaultReadOnly() {
+        return defaultReadOnly;
     }
 
     /**
-     * <p>
-     * Returns 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.
-     * </p>
-     *
-     * <p>
-     * When {@link #getMinEvictableIdleTimeMillis() 
minEvictableIdleTimeMillis} is set to a positive value,
-     * minEvictableIdleTimeMillis is examined first by the idle connection 
evictor - i.e. when idle connections are
-     * visited by the evictor, idle time is first compared against {@code 
minEvictableIdleTimeMillis} (without
-     * considering the number of idle connections in the pool) and then 
against {@code softMinEvictableIdleTimeMillis},
-     * including the {@code minIdle}, constraint.
-     * </p>
+     * Returns the default schema.
      *
-     * @return 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
+     * @return the default schema.
+     * @since 2.5.0
      */
     @Override
-    public synchronized long getSoftMinEvictableIdleTimeMillis() {
-        return softMinEvictableIdleTimeMillis;
+    public String getDefaultSchema() {
+        return this.defaultSchema;
     }
 
-    private String evictionPolicyClassName = 
BaseObjectPoolConfig.DEFAULT_EVICTION_POLICY_CLASS_NAME;
-
     /**
-     * Gets the EvictionPolicy implementation in use with this connection pool.
+     * Returns the default transaction isolation state of returned connections.
      *
-     * @return The EvictionPolicy implementation in use with this connection 
pool.
+     * @return the default value for transaction isolation state
+     * @see Connection#getTransactionIsolation
      */
-    public synchronized String getEvictionPolicyClassName() {
-        return evictionPolicyClassName;
+    @Override
+    public int getDefaultTransactionIsolation() {
+        return this.defaultTransactionIsolation;
     }
 
     /**
-     * Sets the EvictionPolicy implementation to use with this connection pool.
+     * Returns the set of SQL_STATE codes considered to signal fatal 
conditions.
      *
-     * @param evictionPolicyClassName
-     *            The fully qualified class name of the EvictionPolicy 
implementation
+     * @return fatal disconnection state codes
+     * @see #setDisconnectionSqlCodes(Collection)
+     * @since 2.1
      */
-    public synchronized void setEvictionPolicyClassName(final String 
evictionPolicyClassName) {
-        if (connectionPool != null) {
-            connectionPool.setEvictionPolicyClassName(evictionPolicyClassName);
+    public Set<String> getDisconnectionSqlCodes() {
+        final Set<String> result = disconnectionSqlCodes;
+        if (result == null) {
+            return Collections.emptySet();
         }
-        this.evictionPolicyClassName = evictionPolicyClassName;
+        return result;
     }
 
     /**
-     * The indication of whether objects will be validated by the idle object 
evictor (if any). If an object fails to
-     * validate, it will be dropped from the pool.
-     */
-    private boolean testWhileIdle = false;
-
-    /**
-     * Returns the value of the {@link #testWhileIdle} property.
+     * Provides the same data as {@link #getDisconnectionSqlCodes} but in an 
array so it is accessible via JMX.
      *
-     * @return true if objects examined by the idle object evictor are 
validated
-     * @see #testWhileIdle
+     * @since 2.1
      */
     @Override
-    public synchronized boolean getTestWhileIdle() {
-        return this.testWhileIdle;
+    public String[] getDisconnectionSqlCodesAsArray() {
+        final Collection<String> result = getDisconnectionSqlCodes();
+        return result.toArray(new String[result.size()]);
     }
 
     /**
-     * Sets the <code>testWhileIdle</code> property. This property determines 
whether or not the idle object evictor
-     * will validate connections.
+     * Returns the JDBC Driver that has been configured for use by this pool.
+     * <p>
+     * Note: This getter only returns the last value set by a call to {@link 
#setDriver(Driver)}. It does not return any
+     * driver instance that may have been created from the value set via 
{@link #setDriverClassName(String)}.
+     * </p>
      *
-     * @param testWhileIdle
-     *            new value for testWhileIdle property
+     * @return the JDBC Driver that has been configured for use by this pool
      */
-    public synchronized void setTestWhileIdle(final boolean testWhileIdle) {
-        this.testWhileIdle = testWhileIdle;
-        if (connectionPool != null) {
-            connectionPool.setTestWhileIdle(testWhileIdle);
-        }
+    public synchronized Driver getDriver() {
+        return driver;
     }
 
     /**
-     * [Read Only] The current number of active connections that have been 
allocated from this data source.
+     * Returns the class loader specified for loading the JDBC driver. Returns 
<code>null</code> if no class loader has
+     * been explicitly specified.
+     * <p>
+     * Note: This getter only returns the last value set by a call to {@link 
#setDriverClassLoader(ClassLoader)}. It
+     * does not return the class loader of any driver that may have been set 
via {@link #setDriver(Driver)}.
+     * </p>
      *
-     * @return the current number of active connections
+     * @return The class loader specified for loading the JDBC driver.
      */
-    @Override
-    public int getNumActive() {
-        // Copy reference to avoid NPE if close happens after null check
-        final GenericObjectPool<PoolableConnection> pool = connectionPool;
-        if (pool != null) {
-            return pool.getNumActive();
-        }
-        return 0;
+    public synchronized ClassLoader getDriverClassLoader() {
+        return this.driverClassLoader;
     }
 
     /**
-     * [Read Only] The current number of idle connections that are waiting to 
be allocated from this data source.
+     * Returns the JDBC driver class name.
+     * <p>
+     * Note: This getter only returns the last value set by a call to {@link 
#setDriverClassName(String)}. It does not
+     * return the class name of any driver that may have been set via {@link 
#setDriver(Driver)}.
+     * </p>
      *
-     * @return the current number of idle connections
+     * @return the JDBC driver class name
      */
     @Override
-    public int getNumIdle() {
-        // Copy reference to avoid NPE if close happens after null check
-        final GenericObjectPool<PoolableConnection> pool = connectionPool;
-        if (pool != null) {
-            return pool.getNumIdle();
-        }
-        return 0;
+    public synchronized String getDriverClassName() {
+        return this.driverClassName;
     }
 
     /**
-     * The connection password to be passed to our JDBC driver to establish a 
connection.
-     */
-    private volatile String password;
-
-    /**
-     * Returns the password passed to the JDBC driver to establish connections.
+     * Returns the value of the flag that controls whether or not connections 
being returned to the pool will be checked
+     * 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.
      *
-     * @return the connection password
+     * @return Whether or not connections being returned to the pool will be 
checked and configured with auto-commit.
+     * @deprecated Use {@link #getAutoCommitOnReturn()}.
      */
-    @Override
-    public String getPassword() {
-        return this.password;
+    @Deprecated
+    public boolean getEnableAutoCommitOnReturn() {
+        return autoCommitOnReturn;
     }
 
     /**
-     * <p>
-     * Sets the {@link #password}.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been 
initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, 
setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
+     * Gets the EvictionPolicy implementation in use with this connection pool.
      *
-     * @param password
-     *            new value for the password
+     * @return The EvictionPolicy implementation in use with this connection 
pool.
      */
-    public void setPassword(final String password) {
-        this.password = password;
+    public synchronized String getEvictionPolicyClassName() {
+        return evictionPolicyClassName;
     }
 
     /**
-     * The connection URL to be passed to our JDBC driver to establish a 
connection.
-     */
-    private String url;
-
-    /**
-     * Returns the JDBC connection {@link #url} property.
+     * True means that validation will fail immediately for connections that 
have previously thrown SQLExceptions with
+     * SQL_STATE indicating fatal disconnection errors.
      *
-     * @return the {@link #url} passed to the JDBC driver to establish 
connections
+     * @return true if connections created by this datasource will fast fail 
validation.
+     * @see #setDisconnectionSqlCodes(Collection)
+     * @since 2.1
      */
     @Override
-    public synchronized String getUrl() {
-        return this.url;
+    public boolean getFastFailValidation() {
+        return fastFailValidation;
     }
 
     /**
-     * <p>
-     * Sets the {@link #url}.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been 
initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, 
setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
+     * Returns the initial size of the connection pool.
      *
-     * @param url
-     *            the new value for the JDBC connection url
+     * @return the number of connections created when the pool is initialized
      */
-    public synchronized void setUrl(final String url) {
-        this.url = url;
+    @Override
+    public synchronized int getInitialSize() {
+        return this.initialSize;
     }
 
     /**
-     * The connection user name to be passed to our JDBC driver to establish a 
connection.
+     * Returns the JMX name that has been requested for this DataSource. If 
the requested name is not valid, an
+     * alternative may be chosen.
+     *
+     * @return The JMX name that has been requested for this DataSource.
      */
-    private String userName;
+    public String getJmxName() {
+        return jmxName;
+    }
 
     /**
-     * Returns the JDBC connection {@link #userName} property.
+     * Returns the LIFO property.
      *
-     * @return the {@link #userName} passed to the JDBC driver to establish 
connections
+     * @return true if connection pool behaves as a LIFO queue.
      */
     @Override
-    public String getUsername() {
-        return this.userName;
+    public synchronized boolean getLifo() {
+        return this.lifo;
     }
 
     /**
      * <p>
-     * Sets the {@link #userName}.
+     * Flag to log stack traces for application code which abandoned a 
Statement or Connection.
      * </p>
      * <p>
-     * Note: this method currently has no effect once the pool has been 
initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, 
setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * Defaults to false.
+     * </p>
+     * <p>
+     * Logging of abandoned Statements and Connections adds overhead for every 
Connection open or new Statement because
+     * a stack trace has to be generated.
      * </p>
-     *
-     * @param userName
-     *            the new value for the JDBC connection user name
      */
-    public void setUsername(final String userName) {
-        this.userName = userName;
+    @Override
+    public boolean getLogAbandoned() {
+        if (abandonedConfig != null) {
+            return abandonedConfig.getLogAbandoned();
+        }
+        return false;
     }
 
     /**
-     * The SQL query that will be used to validate connections from this pool 
before returning them to the caller. If
-     * specified, this query <strong>MUST</strong> be an SQL SELECT statement 
that returns at least one row. If not
-     * specified, {@link Connection#isValid(int)} will be used to validate 
connections.
-     */
-    private volatile String validationQuery;
-
-    /**
-     * Returns the validation query used to validate connections before 
returning them.
+     * When {@link #getMaxConnLifetimeMillis()} is set to limit connection 
lifetime, this property determines whether or
+     * not log messages are generated when the pool closes connections due to 
maximum lifetime exceeded.
      *
-     * @return the SQL validation query
-     * @see #validationQuery
+     * @since 2.1
      */
     @Override
-    public String getValidationQuery() {
-        return this.validationQuery;
+    public boolean getLogExpiredConnections() {
+        return logExpiredConnections;
     }
 
     /**
+     * <strong>BasicDataSource does NOT support this method.</strong>
+     *
      * <p>
-     * Sets the {@link #validationQuery}.
+     * Returns the login timeout (in seconds) for connecting to the database.
      * </p>
      * <p>
-     * Note: this method currently has no effect once the pool has been 
initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, 
setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * Calls {@link #createDataSource()}, so has the side effect of 
initializing the connection pool.
      * </p>
      *
-     * @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 {
-            this.validationQuery = null;
-        }
-    }
-
-    /**
-     * Timeout in seconds before connection validation queries fail.
-     */
-    private volatile int validationQueryTimeoutSeconds = -1;
-
-    /**
-     * Returns the validation query timeout.
-     *
-     * @return the timeout in seconds before connection validation queries 
fail.
+     * @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 getValidationQueryTimeout() {
-        return validationQueryTimeoutSeconds;
+    public int getLoginTimeout() throws SQLException {
+        // This method isn't supported by the PoolingDataSource returned by 
the createDataSource
+        throw new UnsupportedOperationException("Not supported by 
BasicDataSource");
     }
 
     /**
-     * Sets the validation query timeout, the amount of time, in seconds, that 
connection validation will wait for a
-     * response from the database when executing a validation query. Use a 
value less than or equal to 0 for no timeout.
      * <p>
-     * Note: this method currently has no effect once the pool has been 
initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, 
setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * Returns the log writer being used by this data source.
      * </p>
-     *
-     * @param validationQueryTimeoutSeconds
-     *            new validation query timeout value in seconds
-     */
-    public void setValidationQueryTimeout(final int 
validationQueryTimeoutSeconds) {
-        this.validationQueryTimeoutSeconds = validationQueryTimeoutSeconds;
-    }
-
-    /**
-     * 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
-     * after connection creation.
+     * Calls {@link #createDataSource()}, so has the side effect of 
initializing the connection pool.
      * </p>
-     */
-    private volatile List<String> connectionInitSqls;
-
-    /**
-     * 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.
      *
-     * @return initialization SQL statements
+     * @throws SQLException
+     *             if a database access error occurs
+     * @return log writer in use
      */
-    public List<String> getConnectionInitSqls() {
-        final List<String> result = connectionInitSqls;
-        if (result == null) {
-            return Collections.emptyList();
-        }
-        return result;
+    @Override
+    public PrintWriter getLogWriter() throws SQLException {
+        return createDataSource().getLogWriter();
     }
 
     /**
-     * Provides the same data as {@link #getConnectionInitSqls()} but in an 
array so it is accessible via JMX.
+     * Returns the maximum permitted lifetime of a connection in milliseconds. 
A value of zero or less indicates an
+     * infinite lifetime.
      */
     @Override
-    public String[] getConnectionInitSqlsAsArray() {
-        final Collection<String> result = getConnectionInitSqls();
-        return result.toArray(new String[result.size()]);
+    public long getMaxConnLifetimeMillis() {
+        return maxConnLifetimeMillis;
     }
 
     /**
-     * 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
-     * time one of the following methods is invoked: <code>getConnection, 
setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * Returns the maximum number of connections that can remain idle in the 
pool. Excess idle connections are destroyed
+     * on return to the pool.
+     * </p>
+     * <p>
+     * A negative value indicates that there is no limit
      * </p>
      *
-     * @param connectionInitSqls
-     *            Collection of SQL statements to execute on connection 
creation
+     * @return the maximum number of idle connections
      */
-    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 (newVal == null) {
-                        newVal = new ArrayList<>();
-                    }
-                    newVal.add(s);
-                }
-            }
-            this.connectionInitSqls = newVal;
-        } else {
-            this.connectionInitSqls = null;
-        }
+    @Override
+    public synchronized int getMaxIdle() {
+        return this.maxIdle;
     }
 
     /**
-     * Controls access to the underlying connection.
-     */
-    private boolean accessToUnderlyingConnectionAllowed = false;
-
-    /**
-     * Returns the value of the accessToUnderlyingConnectionAllowed property.
+     * Gets the value of the <code>maxOpenPreparedStatements</code> property.
      *
-     * @return true if access to the underlying connection is allowed, false 
otherwise.
+     * @return the maximum number of open statements
      */
     @Override
-    public synchronized boolean isAccessToUnderlyingConnectionAllowed() {
-        return this.accessToUnderlyingConnectionAllowed;
+    public synchronized int getMaxOpenPreparedStatements() {
+        return this.maxOpenPreparedStatements;
     }
 
     /**
      * <p>
-     * Sets the value of the accessToUnderlyingConnectionAllowed property. It 
controls if the PoolGuard allows access to
-     * the underlying connection. (Default: false)
+     * Returns the maximum number of active connections that can be allocated 
at the same time.
      * </p>
      * <p>
-     * Note: this method currently has no effect once the pool has been 
initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, 
setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
+     * A negative number means that there is no limit.
      * </p>
      *
-     * @param allow
-     *            Access to the underlying connection is granted when true.
+     * @return the maximum number of active connections
      */
-    public synchronized void setAccessToUnderlyingConnectionAllowed(final 
boolean allow) {
-        this.accessToUnderlyingConnectionAllowed = allow;
+    @Override
+    public synchronized int getMaxTotal() {
+        return this.maxTotal;
     }
 
-    private long maxConnLifetimeMillis = -1;
-
     /**
-     * Returns the maximum permitted lifetime of a connection in milliseconds. 
A value of zero or less indicates an
-     * infinite lifetime.
+     * Returns the maximum number of milliseconds that the pool will wait for 
a connection to be returned before
+     * throwing an exception. A value less than or equal to zero means the 
pool is set to wait indefinitely.
+     *
+     * @return the maxWaitMillis property value
      */
     @Override
-    public long getMaxConnLifetimeMillis() {
-        return maxConnLifetimeMillis;
+    public synchronized long getMaxWaitMillis() {
+        return this.maxWaitMillis;
     }
 
-    private boolean logExpiredConnections = true;
-
     /**
-     * When {@link #getMaxConnLifetimeMillis()} is set to limit connection 
lifetime, this property determines whether or
-     * not log messages are generated when the pool closes connections due to 
maximum lifetime exceeded.
+     * Returns the {@link #minEvictableIdleTimeMillis} property.
      *
-     * @since 2.1
+     * @return the value of the {@link #minEvictableIdleTimeMillis} property
+     * @see #minEvictableIdleTimeMillis
      */
     @Override
-    public boolean getLogExpiredConnections() {
-        return logExpiredConnections;
+    public synchronized long getMinEvictableIdleTimeMillis() {
+        return this.minEvictableIdleTimeMillis;
     }
 
     /**
-     * <p>
-     * Sets the maximum permitted lifetime of a connection in milliseconds. A 
value of zero or less indicates an
-     * infinite lifetime.
-     * </p>
-     * <p>
-     * Note: this method currently has no effect once the pool has been 
initialized. The pool is initialized the first
-     * time one of the following methods is invoked: <code>getConnection, 
setLogwriter,
-     * setLoginTimeout, getLoginTimeout, getLogWriter.</code>
-     * </p>
+     * Returns 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 maxConnLifetimeMillis
-     *            The maximum permitted lifetime of a connection in 
milliseconds.
+     * @return the minimum number of idle connections
+     * @see GenericObjectPool#getMinIdle()
      */
-    public void setMaxConnLifetimeMillis(final long maxConnLifetimeMillis) {
-        this.maxConnLifetimeMillis = maxConnLifetimeMillis;
+    @Override
+    public synchronized int getMinIdle() {
+        return this.minIdle;
     }
 
     /**
-     * When {@link #getMaxConnLifetimeMillis()} is set to limit connection 
lifetime, this property determines whether or
-     * 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.
+     * [Read Only] The current number of active connections that have been 
allocated from this data source.
      *
-     * @param logExpiredConnections
-     *            Whether or not log messages are generated when the pool 
closes connections due to maximum lifetime
-     *            exceeded.
+     * @return the current number of active connections
      */
-    public void setLogExpiredConnections(final boolean logExpiredConnections) {
-        this.logExpiredConnections = logExpiredConnections;
+    @Override
+    public int getNumActive() {
+        // Copy reference to avoid NPE if close happens after null check
+        final GenericObjectPool<PoolableConnection> pool = connectionPool;
+        if (pool != null) {
+            return pool.getNumActive();
+        }
+        return 0;
     }
 
-    private String jmxName;
+    /**
+     * [Read Only] The current number of idle connections that are waiting to 
be allocated from this data source.
+     *
+     * @return the current number of idle connections
+     */
+    @Override
+    public int getNumIdle() {
+        // Copy reference to avoid NPE if close happens after null check
+        final GenericObjectPool<PoolableConnection> pool = connectionPool;
+        if (pool != null) {
+            return pool.getNumIdle();
+        }
+        return 0;
+    }
 
     /**
-     * Returns the JMX name that has been requested for this DataSource. If 
the requested name is not valid, an
-     * alternative may be chosen.
+     * Returns the value of the {@link #numTestsPerEvictionRun} property.
      *
-     * @return The JMX name that has been requested for this DataSource.
+     * @return the number of objects to examine during idle object evictor runs
+     * @see #numTestsPerEvictionRun
      */
-    public String getJmxName() {
-        return jmxName;
+    @Override
+    public synchronized int getNumTestsPerEvictionRun() {
+        return this.numTestsPerEvictionRun;
+    }
+
+    @Override
+    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
+        throw new SQLFeatureNotSupportedException();
     }
 
     /**
-     * Sets the JMX name that has been requested for this DataSource. If the 
requested name is not valid, an alternative
-     * may be chosen. This DataSource will attempt to register itself using 
this name. If another component registers
-     * this DataSource with JMX and this name is valid this name will be used 
in preference to any specified by the
-     * other component.
+     * Returns the password passed to the JDBC driver to establish connections.
      *
-     * @param jmxName
-     *            The JMX name that has been requested for this DataSource
+     * @return the connection password
      */
-    public void setJmxName(final String jmxName) {
-        this.jmxName = jmxName;
+    @Override
+    public String getPassword() {
+        return this.password;
     }
 
-    private boolean enableAutoCommitOnReturn = true;
+    protected ObjectName getRegisteredJmxName() {
+        return ObjectNameWrapper.unwrap(registeredJmxObjectName);
+    }
 
     /**
-     * Returns the value of the flag that controls whether or not connections 
being returned to the pool will be checked
-     * and configured with {@link Connection#setAutoCommit(boolean) 
Connection.setAutoCommit(true)} if the auto commi

<TRUNCATED>

Reply via email to