You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2018/06/19 11:21:13 UTC

svn commit: r1833816 [16/16] - in /tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2: ./ cpdsadapter/ datasources/

Modified: tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/SharedPoolDataSource.java
URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/SharedPoolDataSource.java?rev=1833816&r1=1833815&r2=1833816&view=diff
==============================================================================
--- tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/SharedPoolDataSource.java (original)
+++ tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/SharedPoolDataSource.java Tue Jun 19 11:21:13 2018
@@ -32,20 +32,20 @@ import org.apache.tomcat.dbcp.pool2.impl
 import org.apache.tomcat.dbcp.pool2.impl.GenericKeyedObjectPoolConfig;
 
 /**
- * <p>A pooling <code>DataSource</code> appropriate for deployment within
- * J2EE environment.  There are many configuration options, most of which are
- * defined in the parent class. All users (based on username) share a single
- * maximum number of Connections in this datasource.</p>
+ * <p>
+ * A pooling <code>DataSource</code> appropriate for deployment within J2EE environment. There are many configuration
+ * options, most of which are defined in the parent class. All users (based on user name) share a single maximum number
+ * of Connections in this data source.
+ * </p>
  *
- * <p>User passwords can be changed without re-initializing the datasource.
- * When a <code>getConnection(username, password)</code> request is processed
- * with a password that is different from those used to create connections in the
- * pool associated with <code>username</code>, an attempt is made to create a
- * new connection using the supplied password and if this succeeds, idle connections
- * created using the old password are destroyed and new connections are created
- * using the new password.</p>
+ * <p>
+ * User passwords can be changed without re-initializing the data source. When a
+ * <code>getConnection(user name, password)</code> request is processed with a password that is different from those
+ * used to create connections in the pool associated with <code>user name</code>, an attempt is made to create a new
+ * connection using the supplied password and if this succeeds, idle connections created using the old password are
+ * destroyed and new connections are created using the new password.
+ * </p>
  *
- * @author John D. McNally
  * @since 2.0
  */
 public class SharedPoolDataSource extends InstanceKeyDataSource {
@@ -55,18 +55,18 @@ public class SharedPoolDataSource extend
     // Pool properties
     private int maxTotal = GenericKeyedObjectPoolConfig.DEFAULT_MAX_TOTAL;
 
-
-    private transient KeyedObjectPool<UserPassKey,PooledConnectionAndInfo> pool = null;
-    private transient KeyedCPDSConnectionFactory factory = null;
+    private transient KeyedObjectPool<UserPassKey, PooledConnectionAndInfo> pool;
+    private transient KeyedCPDSConnectionFactory factory;
 
     /**
-     * Default no-arg constructor for Serialization
+     * Default no-argument constructor for Serialization
      */
     public SharedPoolDataSource() {
+        // empty.
     }
 
     /**
-     * Close pool being maintained by this datasource.
+     * Closes pool being maintained by this data source.
      */
     @Override
     public void close() throws Exception {
@@ -76,38 +76,45 @@ public class SharedPoolDataSource extend
         InstanceKeyDataSourceFactory.removeInstance(getInstanceKey());
     }
 
-
     // -------------------------------------------------------------------
     // Properties
 
     /**
-     * Set {@link GenericKeyedObjectPool#getMaxTotal()} for this pool.
+     * Gets {@link GenericKeyedObjectPool#getMaxTotal()} for this pool.
+     *
+     * @return {@link GenericKeyedObjectPool#getMaxTotal()} for this pool.
      */
     public int getMaxTotal() {
         return this.maxTotal;
     }
 
     /**
-     * Get {@link GenericKeyedObjectPool#getMaxTotal()} for this pool.
+     * Sets {@link GenericKeyedObjectPool#getMaxTotal()} for this pool.
+     *
+     * @param maxTotal
+     *            {@link GenericKeyedObjectPool#getMaxTotal()} for this pool.
      */
     public void setMaxTotal(final int maxTotal) {
         assertInitializationAllowed();
         this.maxTotal = maxTotal;
     }
 
-
     // ----------------------------------------------------------------------
     // Instrumentation Methods
 
     /**
-     * Get the number of active connections in the pool.
+     * Gets the number of active connections in the pool.
+     *
+     * @return The number of active connections in the pool.
      */
     public int getNumActive() {
         return pool == null ? 0 : pool.getNumActive();
     }
 
     /**
-     * Get the number of idle connections in the pool.
+     * Gets the number of idle connections in the pool.
+     *
+     * @return The number of idle connections in the pool.
      */
     public int getNumIdle() {
         return pool == null ? 0 : pool.getNumIdle();
@@ -117,14 +124,13 @@ public class SharedPoolDataSource extend
     // Inherited abstract methods
 
     @Override
-    protected PooledConnectionAndInfo
-        getPooledConnectionAndInfo(final String username, final String password)
-        throws SQLException {
+    protected PooledConnectionAndInfo getPooledConnectionAndInfo(final String userName, final String userPassword)
+            throws SQLException {
 
-        synchronized(this) {
+        synchronized (this) {
             if (pool == null) {
                 try {
-                    registerPool(username, password);
+                    registerPool(userName, userPassword);
                 } catch (final NamingException e) {
                     throw new SQLException("RegisterPool failed", e);
                 }
@@ -133,20 +139,18 @@ public class SharedPoolDataSource extend
 
         PooledConnectionAndInfo info = null;
 
-        final UserPassKey key = new UserPassKey(username, password);
+        final UserPassKey key = new UserPassKey(userName, userPassword);
 
         try {
             info = pool.borrowObject(key);
-        }
-        catch (final Exception e) {
-            throw new SQLException(
-                    "Could not retrieve connection info from pool", e);
+        } catch (final Exception e) {
+            throw new SQLException("Could not retrieve connection info from pool", e);
         }
         return info;
     }
 
     @Override
-    protected PooledConnectionManager getConnectionManager(final UserPassKey upkey)  {
+    protected PooledConnectionManager getConnectionManager(final UserPassKey upkey) {
         return factory;
     }
 
@@ -155,24 +159,21 @@ public class SharedPoolDataSource extend
      */
     @Override
     public Reference getReference() throws NamingException {
-        final Reference ref = new Reference(getClass().getName(),
-            SharedPoolDataSourceFactory.class.getName(), null);
+        final Reference ref = new Reference(getClass().getName(), SharedPoolDataSourceFactory.class.getName(), null);
         ref.add(new StringRefAddr("instanceKey", getInstanceKey()));
         return ref;
     }
 
-    private void registerPool(final String username, final String password)
-            throws NamingException, SQLException {
+    private void registerPool(final String userName, final String password) throws NamingException, SQLException {
 
-        final ConnectionPoolDataSource cpds = testCPDS(username, password);
+        final ConnectionPoolDataSource cpds = testCPDS(userName, password);
 
         // Create an object pool to contain our PooledConnections
-        factory = new KeyedCPDSConnectionFactory(cpds, getValidationQuery(),
-                getValidationQueryTimeout(), isRollbackAfterValidation());
+        factory = new KeyedCPDSConnectionFactory(cpds, getValidationQuery(), getValidationQueryTimeout(),
+                isRollbackAfterValidation());
         factory.setMaxConnLifetimeMillis(getMaxConnLifetimeMillis());
 
-        final GenericKeyedObjectPoolConfig<PooledConnectionAndInfo> config =
-                new GenericKeyedObjectPoolConfig<>();
+        final GenericKeyedObjectPoolConfig config = new GenericKeyedObjectPoolConfig();
         config.setBlockWhenExhausted(getDefaultBlockWhenExhausted());
         config.setEvictionPolicyClassName(getDefaultEvictionPolicyClassName());
         config.setLifo(getDefaultLifo());
@@ -180,66 +181,58 @@ public class SharedPoolDataSource extend
         config.setMaxTotal(getMaxTotal());
         config.setMaxTotalPerKey(getDefaultMaxTotal());
         config.setMaxWaitMillis(getDefaultMaxWaitMillis());
-        config.setMinEvictableIdleTimeMillis(
-                getDefaultMinEvictableIdleTimeMillis());
+        config.setMinEvictableIdleTimeMillis(getDefaultMinEvictableIdleTimeMillis());
         config.setMinIdlePerKey(getDefaultMinIdle());
         config.setNumTestsPerEvictionRun(getDefaultNumTestsPerEvictionRun());
-        config.setSoftMinEvictableIdleTimeMillis(
-                getDefaultSoftMinEvictableIdleTimeMillis());
+        config.setSoftMinEvictableIdleTimeMillis(getDefaultSoftMinEvictableIdleTimeMillis());
         config.setTestOnCreate(getDefaultTestOnCreate());
         config.setTestOnBorrow(getDefaultTestOnBorrow());
         config.setTestOnReturn(getDefaultTestOnReturn());
         config.setTestWhileIdle(getDefaultTestWhileIdle());
-        config.setTimeBetweenEvictionRunsMillis(
-                getDefaultTimeBetweenEvictionRunsMillis());
+        config.setTimeBetweenEvictionRunsMillis(getDefaultTimeBetweenEvictionRunsMillis());
 
-        final KeyedObjectPool<UserPassKey,PooledConnectionAndInfo> tmpPool =
-                new GenericKeyedObjectPool<>(factory, config);
+        final KeyedObjectPool<UserPassKey, PooledConnectionAndInfo> tmpPool = new GenericKeyedObjectPool<>(factory,
+                config);
         factory.setPool(tmpPool);
         pool = tmpPool;
     }
 
     @Override
-    protected void setupDefaults(final Connection con, final String username) throws SQLException {
+    protected void setupDefaults(final Connection connection, final String userName) throws SQLException {
         final Boolean defaultAutoCommit = isDefaultAutoCommit();
-        if (defaultAutoCommit != null &&
-                con.getAutoCommit() != defaultAutoCommit.booleanValue()) {
-            con.setAutoCommit(defaultAutoCommit.booleanValue());
+        if (defaultAutoCommit != null && connection.getAutoCommit() != defaultAutoCommit.booleanValue()) {
+            connection.setAutoCommit(defaultAutoCommit.booleanValue());
         }
 
         final int defaultTransactionIsolation = getDefaultTransactionIsolation();
         if (defaultTransactionIsolation != UNKNOWN_TRANSACTIONISOLATION) {
-            con.setTransactionIsolation(defaultTransactionIsolation);
+            connection.setTransactionIsolation(defaultTransactionIsolation);
         }
 
         final Boolean defaultReadOnly = isDefaultReadOnly();
-        if (defaultReadOnly != null &&
-                con.isReadOnly() != defaultReadOnly.booleanValue()) {
-            con.setReadOnly(defaultReadOnly.booleanValue());
+        if (defaultReadOnly != null && connection.isReadOnly() != defaultReadOnly.booleanValue()) {
+            connection.setReadOnly(defaultReadOnly.booleanValue());
         }
     }
 
     /**
      * Supports Serialization interface.
      *
-     * @param in a <code>java.io.ObjectInputStream</code> value
-     * @throws IOException if an error occurs
-     * @throws ClassNotFoundException if an error occurs
-     */
-    private void readObject(final ObjectInputStream in)
-        throws IOException, ClassNotFoundException {
-        try
-        {
+     * @param in
+     *            a <code>java.io.ObjectInputStream</code> value
+     * @throws IOException
+     *             if an error occurs
+     * @throws ClassNotFoundException
+     *             if an error occurs
+     */
+    private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
+        try {
             in.defaultReadObject();
-            final SharedPoolDataSource oldDS = (SharedPoolDataSource)
-                new SharedPoolDataSourceFactory()
+            final SharedPoolDataSource oldDS = (SharedPoolDataSource) new SharedPoolDataSourceFactory()
                     .getObjectInstance(getReference(), null, null, null);
             this.pool = oldDS.pool;
-        }
-        catch (final NamingException e)
-        {
+        } catch (final NamingException e) {
             throw new IOException("NamingException: " + e);
         }
     }
 }
-

Modified: tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/SharedPoolDataSourceFactory.java
URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/SharedPoolDataSourceFactory.java?rev=1833816&r1=1833815&r2=1833816&view=diff
==============================================================================
--- tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/SharedPoolDataSourceFactory.java (original)
+++ tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/SharedPoolDataSourceFactory.java Tue Jun 19 11:21:13 2018
@@ -22,13 +22,11 @@ import javax.naming.Reference;
 
 /**
  * A JNDI ObjectFactory which creates <code>SharedPoolDataSource</code>s
+ *
  * @since 2.0
  */
-public class SharedPoolDataSourceFactory
-    extends InstanceKeyDataSourceFactory
-{
-    private static final String SHARED_POOL_CLASSNAME =
-        SharedPoolDataSource.class.getName();
+public class SharedPoolDataSourceFactory extends InstanceKeyDataSourceFactory {
+    private static final String SHARED_POOL_CLASSNAME = SharedPoolDataSource.class.getName();
 
     @Override
     protected boolean isCorrectClass(final String className) {
@@ -40,10 +38,8 @@ public class SharedPoolDataSourceFactory
         final SharedPoolDataSource spds = new SharedPoolDataSource();
         final RefAddr ra = ref.get("maxTotal");
         if (ra != null && ra.getContent() != null) {
-            spds.setMaxTotal(
-                Integer.parseInt(ra.getContent().toString()));
+            spds.setMaxTotal(Integer.parseInt(ra.getContent().toString()));
         }
         return spds;
     }
 }
-

Modified: tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/UserPassKey.java
URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/UserPassKey.java?rev=1833816&r1=1833815&r2=1833816&view=diff
==============================================================================
--- tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/UserPassKey.java (original)
+++ tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/datasources/UserPassKey.java Tue Jun 19 11:21:13 2018
@@ -19,85 +19,115 @@ package org.apache.tomcat.dbcp.dbcp2.dat
 
 import java.io.Serializable;
 
+import org.apache.tomcat.dbcp.dbcp2.Utils;
+
 /**
- * <p>Holds a username, password pair.  Serves as a poolable object key for the KeyedObjectPool
- * backing a SharedPoolDataSource.  Two instances with the same username are considered equal.
- * This ensures that there will be only one keyed pool for each user in the pool.  The password
- * is used (along with the username) by the KeyedCPDSConnectionFactory when creating new connections.</p>
+ * <p>
+ * Holds a user name and password pair. Serves as a poolable object key for the KeyedObjectPool backing a
+ * SharedPoolDataSource. Two instances with the same user name are considered equal. This ensures that there will be
+ * only one keyed pool for each user in the pool. The password is used (along with the user name) by the
+ * KeyedCPDSConnectionFactory when creating new connections.
+ * </p>
  *
- * <p>{@link InstanceKeyDataSource#getConnection(String, String)} validates that the password used to create
- * a connection matches the password provided by the client.</p>
+ * <p>
+ * {@link InstanceKeyDataSource#getConnection(String, String)} validates that the password used to create a connection
+ * matches the password provided by the client.
+ * </p>
  *
  * @since 2.0
  */
 class UserPassKey implements Serializable {
     private static final long serialVersionUID = 5142970911626584817L;
-    private final String password;
-    private final String username;
-
-    UserPassKey(final String username, final String password) {
-        this.username = username;
-        this.password = password;
-    }
+    private final String userName;
+    private final char[] userPassword;
 
     /**
-     * Get the value of password.
-     * @return value of password.
+     * @since 2.4.0
      */
-    public String getPassword() {
-        return password;
+    UserPassKey(final String userName) {
+        this(userName, (char[]) null);
     }
 
     /**
-     * Get the value of username.
-     * @return value of username.
+     * @since 2.4.0
      */
-    public String getUsername() {
-        return username;
+    UserPassKey(final String userName, final char[] password) {
+        this.userName = userName;
+        this.userPassword = password;
+    }
+
+    UserPassKey(final String userName, final String userPassword) {
+        this(userName, Utils.toCharArray(userPassword));
     }
 
     /**
-     * @return <code>true</code> if the username fields for both
-     * objects are equal.  Two instances with the same username
-     * but different passwords are considered equal.
-     *
-     * @see java.lang.Object#equals(java.lang.Object)
+     * Only takes the user name into account.
      */
     @Override
     public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
         if (obj == null) {
             return false;
         }
-
-        if (obj == this) {
-            return true;
+        if (getClass() != obj.getClass()) {
+            return false;
         }
-
-        if (!(obj instanceof UserPassKey)) {
+        final UserPassKey other = (UserPassKey) obj;
+        if (userName == null) {
+            if (other.userName != null) {
+                return false;
+            }
+        } else if (!userName.equals(other.userName)) {
             return false;
         }
+        return true;
+    }
 
-        final UserPassKey key = (UserPassKey) obj;
+    /**
+     * Gets the value of password.
+     *
+     * @return value of password.
+     */
+    public String getPassword() {
+        return Utils.toString(userPassword);
+    }
+
+    /**
+     * Gets the value of password.
+     *
+     * @return value of password.
+     */
+    public char[] getPasswordCharArray() {
+        return userPassword;
+    }
 
-        return this.username == null ?
-                key.username == null :
-                this.username.equals(key.username);
+    /**
+     * Gets the value of user name.
+     *
+     * @return value of user name.
+     */
+    public String getUsername() {
+        return userName;
     }
 
     /**
-     * Returns the hash of the username.
+     * Only takes the user name into account.
      */
     @Override
     public int hashCode() {
-        return this.username != null ?
-                this.username.hashCode() : 0;
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((userName == null) ? 0 : userName.hashCode());
+        return result;
     }
 
     @Override
     public String toString() {
         final StringBuffer sb = new StringBuffer(50);
         sb.append("UserPassKey(");
-        sb.append(username).append(", ").append(password).append(')');
+        sb.append(userName).append(", ").append(userPassword).append(')');
         return sb.toString();
     }
 }

Modified: tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/package-info.java
URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/package-info.java?rev=1833816&r1=1833815&r2=1833816&view=diff
==============================================================================
--- tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/package-info.java (original)
+++ tomcat/tc8.0.x/trunk/java/org/apache/tomcat/dbcp/dbcp2/package-info.java Tue Jun 19 11:21:13 2018
@@ -17,114 +17,115 @@
 
 /**
  * <p>
- *    Database Connection Pool API.
+ * Database Connection Pool API.
  * </p>
  *
  * <b>Overview in Dialog Form</b>
  * <p>
- *    Q: How do I use the DBCP package?
- * </p><p>
- *    A: There are two primary ways to access the DBCP pool, as a
- *    {@link java.sql.Driver Driver}, or as a {@link javax.sql.DataSource DataSource}.
- *    You'll want to create an instance of {@link org.apache.tomcat.dbcp.dbcp2.PoolingDriver} or
- *    {@link org.apache.tomcat.dbcp.dbcp2.PoolingDataSource}.  When using one of these
- *    interfaces, you can just use your JDBC objects the way you normally would.
- *    Closing a {@link java.sql.Connection} will simply return it to its pool.
- * </p>
- * <p>
- *    Q: But {@link org.apache.tomcat.dbcp.dbcp2.PoolingDriver PoolingDriver} and
- *    {@link org.apache.tomcat.dbcp.dbcp2.PoolingDataSource PoolingDataSource} both expect an
- *    {@link org.apache.tomcat.dbcp.pool2.ObjectPool ObjectPool} as an input.  Where do I
- *    get one of those?
- * </p><p>
- *    A: The {@link org.apache.tomcat.dbcp.pool2.ObjectPool ObjectPool} interface is defined
- *    in Commons Pool. You can use one of the provided implementations such as
- *    {@link org.apache.tomcat.dbcp.pool2.impl.GenericObjectPool GenericObjectPool} or
- *    {@link org.apache.tomcat.dbcp.pool2.impl.SoftReferenceObjectPool SoftReferenceObjectPool}
- *    or you can create your own.
- * </p>
- * <p>
- *    Q: Ok, I've found an {@link org.apache.tomcat.dbcp.pool2.ObjectPool ObjectPool}
- *    implementation that I think suits my connection pooling needs.  But it wants
- *    a {@link org.apache.tomcat.dbcp.pool2.PooledObjectFactory PooledObjectFactory}.
- *    What should I use for that?
- * </p><p>
- *    A: The DBCP package provides a class for this purpose. It's called
- *    {@link org.apache.tomcat.dbcp.dbcp2.PoolableConnectionFactory}.
- *    It implements the factory and lifecycle methods of
- *    {@link org.apache.tomcat.dbcp.pool2.PooledObjectFactory}
- *    for {@link java.sql.Connection}s.  But it doesn't create the actual database
- *    {@link java.sql.Connection}s itself, it uses a
- *    {@link org.apache.tomcat.dbcp.dbcp2.ConnectionFactory} for that.
- *    The {@link org.apache.tomcat.dbcp.dbcp2.PoolableConnectionFactory} will take
- *    {@link java.sql.Connection}s created by the {@link org.apache.tomcat.dbcp.dbcp2.ConnectionFactory}
- *    and wrap them with classes that implement the pooling behaviour.
- * </p><p>
- *    Several implementations of {@link org.apache.tomcat.dbcp.dbcp2.ConnectionFactory} are
- *    provided--one that uses {@link java.sql.DriverManager} to create connections
- *    ({@link org.apache.tomcat.dbcp.dbcp2.DriverManagerConnectionFactory}),
- *    one that uses a {@link java.sql.Driver} to create connections
- *    ({@link org.apache.tomcat.dbcp.dbcp2.DriverConnectionFactory}),
- *    one that uses a {@link javax.sql.DataSource} to create connections
- *    ({@link org.apache.tomcat.dbcp.dbcp2.DataSourceConnectionFactory}).
- * </p>
- * <p>
- *    Q: I think I'm starting to get it, but can you walk me though it again?
- * </p><p>
- *    A: Sure.  Let's assume you want to create a {@link javax.sql.DataSource}
- *    that pools {@link java.sql.Connection}s.  Let's also assume that
- *    those pooled {@link java.sql.Connection}s should be obtained from
- *    the {@link java.sql.DriverManager}.
- *    You'll want to create a {@link org.apache.tomcat.dbcp.dbcp2.PoolingDataSource}.
- * </p><p>
- *    The {@link org.apache.tomcat.dbcp.dbcp2.PoolingDataSource} uses an underlying
- *    {@link org.apache.tomcat.dbcp.pool2.ObjectPool} to create and store its
- *    {@link java.sql.Connection}.
- * </p><p>
- *    To create a {@link org.apache.tomcat.dbcp.pool2.ObjectPool}, you'll need
- *    a {@link org.apache.tomcat.dbcp.pool2.PooledObjectFactory} that creates
- *    the actual {@link java.sql.Connection}s.  That's what
- *    {@link org.apache.tomcat.dbcp.dbcp2.PoolableConnectionFactory} is for.
- * </p><p>
- *    To create the {@link org.apache.tomcat.dbcp.dbcp2.PoolableConnectionFactory},
- *    you'll need at least two things:</p>
- *    <ol>
- *     <li>
- * A {@link org.apache.tomcat.dbcp.dbcp2.ConnectionFactory} from which
- * the actual database {@link java.sql.Connection}s will be obtained.
- *     </li>
- *     <li>
- * An empty and factory-less {@link org.apache.tomcat.dbcp.pool2.ObjectPool}
- * in which the {@link java.sql.Connection}s will be stored.
- * <br>
+ * Q: How do I use the DBCP package?
+ * </p>
+ * <p>
+ * A: There are two primary ways to access the DBCP pool, as a {@link java.sql.Driver Driver}, or as a
+ * {@link javax.sql.DataSource DataSource}. You'll want to create an instance of
+ * {@link org.apache.tomcat.dbcp.dbcp2.PoolingDriver} or {@link org.apache.tomcat.dbcp.dbcp2.PoolingDataSource}. When using one
+ * of these interfaces, you can just use your JDBC objects the way you normally would. Closing a
+ * {@link java.sql.Connection} will simply return it to its pool.
+ * </p>
+ * <p>
+ * Q: But {@link org.apache.tomcat.dbcp.dbcp2.PoolingDriver PoolingDriver} and
+ * {@link org.apache.tomcat.dbcp.dbcp2.PoolingDataSource PoolingDataSource} both expect an
+ * {@link org.apache.tomcat.dbcp.pool2.ObjectPool ObjectPool} as an input. Where do I get one of those?
+ * </p>
+ * <p>
+ * A: The {@link org.apache.tomcat.dbcp.pool2.ObjectPool ObjectPool} interface is defined in Commons Pool. You can use one
+ * of the provided implementations such as {@link org.apache.tomcat.dbcp.pool2.impl.GenericObjectPool GenericObjectPool} or
+ * {@link org.apache.tomcat.dbcp.pool2.impl.SoftReferenceObjectPool SoftReferenceObjectPool} or you can create your own.
+ * </p>
+ * <p>
+ * Q: Ok, I've found an {@link org.apache.tomcat.dbcp.pool2.ObjectPool ObjectPool} implementation that I think suits my
+ * connection pooling needs. But it wants a {@link org.apache.tomcat.dbcp.pool2.PooledObjectFactory PooledObjectFactory}.
+ * What should I use for that?
+ * </p>
+ * <p>
+ * A: The DBCP package provides a class for this purpose. It's called
+ * {@link org.apache.tomcat.dbcp.dbcp2.PoolableConnectionFactory}. It implements the factory and lifecycle methods of
+ * {@link org.apache.tomcat.dbcp.pool2.PooledObjectFactory} for {@link java.sql.Connection}s. But it doesn't create the
+ * actual database {@link java.sql.Connection}s itself, it uses a {@link org.apache.tomcat.dbcp.dbcp2.ConnectionFactory} for
+ * that. The {@link org.apache.tomcat.dbcp.dbcp2.PoolableConnectionFactory} will take {@link java.sql.Connection}s created
+ * by the {@link org.apache.tomcat.dbcp.dbcp2.ConnectionFactory} and wrap them with classes that implement the pooling
+ * behaviour.
+ * </p>
+ * <p>
+ * Several implementations of {@link org.apache.tomcat.dbcp.dbcp2.ConnectionFactory} are provided--one that uses
+ * {@link java.sql.DriverManager} to create connections
+ * ({@link org.apache.tomcat.dbcp.dbcp2.DriverManagerConnectionFactory}), one that uses a {@link java.sql.Driver} to create
+ * connections ({@link org.apache.tomcat.dbcp.dbcp2.DriverConnectionFactory}), one that uses a {@link javax.sql.DataSource}
+ * to create connections ({@link org.apache.tomcat.dbcp.dbcp2.DataSourceConnectionFactory}).
+ * </p>
+ * <p>
+ * Q: I think I'm starting to get it, but can you walk me though it again?
+ * </p>
+ * <p>
+ * A: Sure. Let's assume you want to create a {@link javax.sql.DataSource} that pools {@link java.sql.Connection}s.
+ * Let's also assume that those pooled {@link java.sql.Connection}s should be obtained from the
+ * {@link java.sql.DriverManager}. You'll want to create a {@link org.apache.tomcat.dbcp.dbcp2.PoolingDataSource}.
+ * </p>
+ * <p>
+ * The {@link org.apache.tomcat.dbcp.dbcp2.PoolingDataSource} uses an underlying {@link org.apache.tomcat.dbcp.pool2.ObjectPool}
+ * to create and store its {@link java.sql.Connection}.
+ * </p>
+ * <p>
+ * To create a {@link org.apache.tomcat.dbcp.pool2.ObjectPool}, you'll need a
+ * {@link org.apache.tomcat.dbcp.pool2.PooledObjectFactory} that creates the actual {@link java.sql.Connection}s. That's
+ * what {@link org.apache.tomcat.dbcp.dbcp2.PoolableConnectionFactory} is for.
+ * </p>
+ * <p>
+ * To create the {@link org.apache.tomcat.dbcp.dbcp2.PoolableConnectionFactory}, you'll need at least two things:
+ * </p>
+ * <ol>
+ * <li>A {@link org.apache.tomcat.dbcp.dbcp2.ConnectionFactory} from which the actual database {@link java.sql.Connection}s
+ * will be obtained.</li>
+ * <li>An empty and factory-less {@link org.apache.tomcat.dbcp.pool2.ObjectPool} in which the {@link java.sql.Connection}s
+ * will be stored. <br>
  * When you pass an {@link org.apache.tomcat.dbcp.pool2.ObjectPool} into the
- * {@link org.apache.tomcat.dbcp.dbcp2.PoolableConnectionFactory}, it will
- * automatically register itself as the {@link org.apache.tomcat.dbcp.pool2.PooledObjectFactory}
- * for that pool.
- *     </li>
- *    </ol>
- * <p>
- *    In code, that might look like this:
- * </p>
- * <pre>GenericObjectPool connectionPool = new GenericObjectPool(null);
- * ConnectionFactory connectionFactory = new DriverManagerConnectionFactory("jdbc:some:connect:string", "username", "password");
- * PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory,connectionPool,null,null,false,true);
- * PoolingDataSource dataSource = new PoolingDataSource(connectionPool);</pre>
- * <p>
- *    To create a {@link org.apache.tomcat.dbcp.dbcp2.PoolingDriver}, we do the same thing,
- *    except that instead of creating a {@link javax.sql.DataSource} on the last line,
- *    we create a {@link org.apache.tomcat.dbcp.dbcp2.PoolingDriver}, and register the
- *    {@code connectionPool} with it.  E.g.,:</p>
- * <pre>GenericObjectPool connectionPool = new GenericObjectPool(null);
- * ConnectionFactory connectionFactory = new DriverManagerConnectionFactory("jdbc:some:connect:string", "username", "password");
- * PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory,connectionPool,null,null,false,true);
+ * {@link org.apache.tomcat.dbcp.dbcp2.PoolableConnectionFactory}, it will automatically register itself as the
+ * {@link org.apache.tomcat.dbcp.pool2.PooledObjectFactory} for that pool.</li>
+ * </ol>
+ * <p>
+ * In code, that might look like this:
+ * </p>
+ *
+ * <pre>
+ * GenericObjectPool connectionPool = new GenericObjectPool(null);
+ * ConnectionFactory connectionFactory = new DriverManagerConnectionFactory("jdbc:some:connect:string", "userName",
+ *         "password");
+ * PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory,
+ *         connectionPool, null, null, false, true);
+ * PoolingDataSource dataSource = new PoolingDataSource(connectionPool);
+ * </pre>
+ * <p>
+ * To create a {@link org.apache.tomcat.dbcp.dbcp2.PoolingDriver}, we do the same thing, except that instead of creating a
+ * {@link javax.sql.DataSource} on the last line, we create a {@link org.apache.tomcat.dbcp.dbcp2.PoolingDriver}, and
+ * register the {@code connectionPool} with it. E.g.,:
+ * </p>
+ *
+ * <pre>
+ * GenericObjectPool connectionPool = new GenericObjectPool(null);
+ * ConnectionFactory connectionFactory = new DriverManagerConnectionFactory("jdbc:some:connect:string", "userName",
+ *         "password");
+ * PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory,
+ *         connectionPool, null, null, false, true);
  * PoolingDriver driver = new PoolingDriver();
- * driver.registerPool("example",connectionPool);</pre>
+ * driver.registerPool("example", connectionPool);
+ * </pre>
  * <p>
- *    Since the {@link org.apache.tomcat.dbcp.dbcp2.PoolingDriver} registers itself
- *    with the {@link java.sql.DriverManager} when it is created, now you can just
- *    go to the {@link java.sql.DriverManager} to create your {@link java.sql.Connection}s,
- *    like you normally would:</p>
- * <pre>Connection conn = DriverManager.getConnection("jdbc:apache:commons:dbcp:example");</pre>
+ * Since the {@link org.apache.tomcat.dbcp.dbcp2.PoolingDriver} registers itself with the {@link java.sql.DriverManager}
+ * when it is created, now you can just go to the {@link java.sql.DriverManager} to create your
+ * {@link java.sql.Connection}s, like you normally would:
+ * </p>
+ *
+ * <pre>
+ * Connection conn = DriverManager.getConnection("jdbc:apache:commons:dbcp:example");
+ * </pre>
  */
 package org.apache.tomcat.dbcp.dbcp2;



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