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 2019/12/06 19:42:59 UTC

[tomcat] 04/09: Merge in Pool 2 changes to 6092f92 (2019-12-06, 2.8.0-SNAPSHOT)

This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 6ad6bfcc66b48d8c9b7cfe2e401b05c94a92ff25
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri Dec 6 15:43:08 2019 +0000

    Merge in Pool 2 changes to 6092f92 (2019-12-06, 2.8.0-SNAPSHOT)
---
 MERGE.txt                                          |  12 +-
 .../dbcp/pool2/BaseKeyedPooledObjectFactory.java   |   2 +
 .../apache/tomcat/dbcp/pool2/BaseObjectPool.java   |   1 +
 .../apache/tomcat/dbcp/pool2/KeyedObjectPool.java  | 227 +++++++++++++--------
 java/org/apache/tomcat/dbcp/pool2/ObjectPool.java  | 138 +++++++------
 java/org/apache/tomcat/dbcp/pool2/PoolUtils.java   |  26 +--
 .../org/apache/tomcat/dbcp/pool2/PooledObject.java |   3 +-
 .../dbcp/pool2/impl/DefaultEvictionPolicy.java     |   2 +
 .../tomcat/dbcp/pool2/impl/EvictionConfig.java     |   1 +
 .../tomcat/dbcp/pool2/impl/EvictionTimer.java      |   9 +-
 .../dbcp/pool2/impl/GenericKeyedObjectPool.java    |  25 ++-
 .../tomcat/dbcp/pool2/impl/GenericObjectPool.java  |  29 +--
 .../pool2/impl/InterruptibleReentrantLock.java     |   1 +
 .../dbcp/pool2/impl/LinkedBlockingDeque.java       |   4 +
 .../dbcp/pool2/impl/SecurityManagerCallStack.java  |   7 +-
 .../dbcp/pool2/impl/SoftReferenceObjectPool.java   |   3 +
 webapps/docs/changelog.xml                         |   4 +
 17 files changed, 294 insertions(+), 200 deletions(-)

diff --git a/MERGE.txt b/MERGE.txt
index 893ac89..7daec6d 100644
--- a/MERGE.txt
+++ b/MERGE.txt
@@ -58,15 +58,15 @@ Note: Tomcat's copy of fileupload also includes classes copied manually from
 
 DBCP
 ----
+Pool2
+Sub-tree
+src/main/java/org/apache/commons/pool2
+The SHA1 ID for the most recent commit to be merged to Tomcat is:
+6092f924b36061353ff92b18c88400ab3bc05327 (2019-12-06)
+
 DBCP2
 Sub-tree
 src/main/java/org/apache/commons/dbcp2
 src/main/resources/org/apache/commons/dbcp2
 The SHA1 ID for the most recent commit to be merged to Tomcat is:
 4813b7f5456c1f4fecc4f701ac731a71f57db249 (2019-08-09)
-
-Pool2
-Sub-tree
-src/main/java/org/apache/commons/pool2
-The SHA1 ID for the most recent commit to be merged to Tomcat is:
-796e32d53cc0d870ba0db3a7faf4c5b24ff76f3f (2019-08-01)
diff --git a/java/org/apache/tomcat/dbcp/pool2/BaseKeyedPooledObjectFactory.java b/java/org/apache/tomcat/dbcp/pool2/BaseKeyedPooledObjectFactory.java
index 3dd7429..dfbc5a9 100644
--- a/java/org/apache/tomcat/dbcp/pool2/BaseKeyedPooledObjectFactory.java
+++ b/java/org/apache/tomcat/dbcp/pool2/BaseKeyedPooledObjectFactory.java
@@ -21,7 +21,9 @@ package org.apache.tomcat.dbcp.pool2;
  * <p>
  * All operations defined here are essentially no-op's.
  * </p>
+ * <p>
  * This class is immutable, and therefore thread-safe.
+ * </p>
  *
  * @see KeyedPooledObjectFactory
  *
diff --git a/java/org/apache/tomcat/dbcp/pool2/BaseObjectPool.java b/java/org/apache/tomcat/dbcp/pool2/BaseObjectPool.java
index 29f189a..df23b12 100644
--- a/java/org/apache/tomcat/dbcp/pool2/BaseObjectPool.java
+++ b/java/org/apache/tomcat/dbcp/pool2/BaseObjectPool.java
@@ -22,6 +22,7 @@ package org.apache.tomcat.dbcp.pool2;
  * indicating it is unsupported or throw {@link UnsupportedOperationException}.
  * <p>
  * This class is intended to be thread-safe.
+ * </p>
  *
  * @param <T> Type of element pooled in this pool.
  *
diff --git a/java/org/apache/tomcat/dbcp/pool2/KeyedObjectPool.java b/java/org/apache/tomcat/dbcp/pool2/KeyedObjectPool.java
index 4df37d8..fc18acc 100644
--- a/java/org/apache/tomcat/dbcp/pool2/KeyedObjectPool.java
+++ b/java/org/apache/tomcat/dbcp/pool2/KeyedObjectPool.java
@@ -17,6 +17,8 @@
 package org.apache.tomcat.dbcp.pool2;
 
 import java.io.Closeable;
+import java.util.Collection;
+import java.util.Iterator;
 import java.util.NoSuchElementException;
 
 /**
@@ -66,6 +68,75 @@ import java.util.NoSuchElementException;
  * @since 2.0
  */
 public interface KeyedObjectPool<K, V> extends Closeable {
+
+    /**
+     * Create an object using the {@link KeyedPooledObjectFactory factory} or
+     * other implementation dependent mechanism, passivate it, and then place it
+     * in the idle object pool. <code>addObject</code> is useful for
+     * "pre-loading" a pool with idle objects (Optional operation).
+     *
+     * @param key the key a new instance should be added to
+     *
+     * @throws Exception
+     *              when {@link KeyedPooledObjectFactory#makeObject} fails.
+     * @throws IllegalStateException
+     *              after {@link #close} has been called on this pool.
+     * @throws UnsupportedOperationException
+     *              when this pool cannot add new idle objects.
+     */
+    void addObject(K key) throws Exception, IllegalStateException,
+            UnsupportedOperationException;
+
+    /**
+     * Calls {@link KeyedObjectPool#addObject(Object)} with each
+     * key in <code>keys</code> for <code>count</code> number of times. This has
+     * the same effect as calling {@link #addObjects(Object, int)}
+     * for each key in the <code>keys</code> collection.
+     *
+     * @param keys
+     *            {@link Collection} of keys to add objects for.
+     * @param count
+     *            the number of idle objects to add for each <code>key</code>.
+     * @throws Exception
+     *             when {@link KeyedObjectPool#addObject(Object)} fails.
+     * @throws IllegalArgumentException
+     *             when <code>keyedPool</code>, <code>keys</code>, or any value
+     *             in <code>keys</code> is <code>null</code>.
+     * @see #addObjects(Object, int)
+     */
+    default void addObjects(final Collection<K> keys, final int count) throws Exception, IllegalArgumentException {
+        if (keys == null) {
+            throw new IllegalArgumentException(PoolUtils.MSG_NULL_KEYS);
+        }
+        final Iterator<K> iter = keys.iterator();
+        while (iter.hasNext()) {
+            addObjects(iter.next(), count);
+        }
+    }
+
+    /**
+     * Calls {@link KeyedObjectPool#addObject(Object)}
+     * <code>key</code> <code>count</code> number of times.
+     *
+     * @param key
+     *            the key to add objects for.
+     * @param count
+     *            the number of idle objects to add for <code>key</code>.
+     * @throws Exception
+     *             when {@link KeyedObjectPool#addObject(Object)} fails.
+     * @throws IllegalArgumentException
+     *             when <code>key</code> is <code>null</code>.
+     * @since 2.8.0
+     */
+    default void addObjects(final K key, final int count) throws Exception, IllegalArgumentException {
+        if (key == null) {
+            throw new IllegalArgumentException(PoolUtils.MSG_NULL_KEY);
+        }
+        for (int i = 0; i < count; i++) {
+            addObject(key);
+        }
+    }
+
     /**
      * Obtains an instance from this pool for the specified <code>key</code>.
      * <p>
@@ -105,75 +176,50 @@ public interface KeyedObjectPool<K, V> extends Closeable {
     V borrowObject(K key) throws Exception, NoSuchElementException, IllegalStateException;
 
     /**
-     * Return an instance to the pool. By contract, <code>obj</code>
-     * <strong>must</strong> have been obtained using
-     * {@link #borrowObject borrowObject} or a related method as defined in an
-     * implementation or sub-interface using a <code>key</code> that is
-     * equivalent to the one used to borrow the instance in the first place.
-     *
-     * @param key the key used to obtain the object
-     * @param obj a {@link #borrowObject borrowed} instance to be returned.
+     * Clears the pool, removing all pooled instances (optional operation).
      *
-     * @throws IllegalStateException
-     *              if an attempt is made to return an object to the pool that
-     *              is in any state other than allocated (i.e. borrowed).
-     *              Attempting to return an object more than once or attempting
-     *              to return an object that was never borrowed from the pool
-     *              will trigger this exception.
+     * @throws UnsupportedOperationException when this implementation doesn't
+     *                                       support the operation
      *
-     * @throws Exception if an instance cannot be returned to the pool
+     * @throws Exception if the pool cannot be cleared
      */
-    void returnObject(K key, V obj) throws Exception;
+    void clear() throws Exception, UnsupportedOperationException;
 
     /**
-     * Invalidates an object from the pool.
-     * <p>
-     * By contract, <code>obj</code> <strong>must</strong> have been obtained
-     * using {@link #borrowObject borrowObject} or a related method as defined
-     * in an implementation or sub-interface using a <code>key</code> that is
-     * equivalent to the one used to borrow the <code>Object</code> in the first
-     * place.
-     * </p>
-     * <p>
-     * This method should be used when an object that has been borrowed is
-     * determined (due to an exception or other problem) to be invalid.
-     * </p>
+     * Clears the specified pool, removing all pooled instances corresponding to
+     * the given <code>key</code> (optional operation).
      *
-     * @param key the key used to obtain the object
-     * @param obj a {@link #borrowObject borrowed} instance to be returned.
+     * @param key the key to clear
      *
-     * @throws Exception if the instance cannot be invalidated
+     * @throws UnsupportedOperationException when this implementation doesn't
+     *                                       support the operation
+     *
+     * @throws Exception if the key cannot be cleared
      */
-    void invalidateObject(K key, V obj) throws Exception;
+    void clear(K key) throws Exception, UnsupportedOperationException;
 
     /**
-     * Create an object using the {@link KeyedPooledObjectFactory factory} or
-     * other implementation dependent mechanism, passivate it, and then place it
-     * in the idle object pool. <code>addObject</code> is useful for
-     * "pre-loading" a pool with idle objects (Optional operation).
-     *
-     * @param key the key a new instance should be added to
-     *
-     * @throws Exception
-     *              when {@link KeyedPooledObjectFactory#makeObject} fails.
-     * @throws IllegalStateException
-     *              after {@link #close} has been called on this pool.
-     * @throws UnsupportedOperationException
-     *              when this pool cannot add new idle objects.
+     * Close this pool, and free any resources associated with it.
+     * <p>
+     * Calling {@link #addObject addObject} or
+     * {@link #borrowObject borrowObject} after invoking this method on a pool
+     * will cause them to throw an {@link IllegalStateException}.
+     * </p>
+     * <p>
+     * Implementations should silently fail if not all resources can be freed.
+     * </p>
      */
-    void addObject(K key) throws Exception, IllegalStateException,
-            UnsupportedOperationException;
+    @Override
+    void close();
 
     /**
-     * Returns the number of instances corresponding to the given
-     * <code>key</code> currently idle in this pool. Returns a negative value if
-     * this information is not available.
-     *
-     * @param key the key to query
-     * @return the number of instances corresponding to the given
-     * <code>key</code> currently idle in this pool.
+     * Returns the total number of instances currently borrowed from this pool but
+     * not yet returned. Returns a negative value if this information is not
+     * available.
+     * @return the total number of instances currently borrowed from this pool but
+     * not yet returned.
      */
-    int getNumIdle(K key);
+    int getNumActive();
 
     /**
      * Returns the number of instances currently borrowed from but not yet
@@ -194,48 +240,55 @@ public interface KeyedObjectPool<K, V> extends Closeable {
     int getNumIdle();
 
     /**
-     * Returns the total number of instances currently borrowed from this pool but
-     * not yet returned. Returns a negative value if this information is not
-     * available.
-     * @return the total number of instances currently borrowed from this pool but
-     * not yet returned.
+     * Returns the number of instances corresponding to the given
+     * <code>key</code> currently idle in this pool. Returns a negative value if
+     * this information is not available.
+     *
+     * @param key the key to query
+     * @return the number of instances corresponding to the given
+     * <code>key</code> currently idle in this pool.
      */
-    int getNumActive();
+    int getNumIdle(K key);
 
     /**
-     * Clears the pool, removing all pooled instances (optional operation).
+     * Invalidates an object from the pool.
+     * <p>
+     * By contract, <code>obj</code> <strong>must</strong> have been obtained
+     * using {@link #borrowObject borrowObject} or a related method as defined
+     * in an implementation or sub-interface using a <code>key</code> that is
+     * equivalent to the one used to borrow the <code>Object</code> in the first
+     * place.
+     * </p>
+     * <p>
+     * This method should be used when an object that has been borrowed is
+     * determined (due to an exception or other problem) to be invalid.
+     * </p>
      *
-     * @throws UnsupportedOperationException when this implementation doesn't
-     *                                       support the operation
+     * @param key the key used to obtain the object
+     * @param obj a {@link #borrowObject borrowed} instance to be returned.
      *
-     * @throws Exception if the pool cannot be cleared
+     * @throws Exception if the instance cannot be invalidated
      */
-    void clear() throws Exception, UnsupportedOperationException;
+    void invalidateObject(K key, V obj) throws Exception;
 
     /**
-     * Clears the specified pool, removing all pooled instances corresponding to
-     * the given <code>key</code> (optional operation).
+     * Return an instance to the pool. By contract, <code>obj</code>
+     * <strong>must</strong> have been obtained using
+     * {@link #borrowObject borrowObject} or a related method as defined in an
+     * implementation or sub-interface using a <code>key</code> that is
+     * equivalent to the one used to borrow the instance in the first place.
      *
-     * @param key the key to clear
+     * @param key the key used to obtain the object
+     * @param obj a {@link #borrowObject borrowed} instance to be returned.
      *
-     * @throws UnsupportedOperationException when this implementation doesn't
-     *                                       support the operation
+     * @throws IllegalStateException
+     *              if an attempt is made to return an object to the pool that
+     *              is in any state other than allocated (i.e. borrowed).
+     *              Attempting to return an object more than once or attempting
+     *              to return an object that was never borrowed from the pool
+     *              will trigger this exception.
      *
-     * @throws Exception if the key cannot be cleared
-     */
-    void clear(K key) throws Exception, UnsupportedOperationException;
-
-    /**
-     * Close this pool, and free any resources associated with it.
-     * <p>
-     * Calling {@link #addObject addObject} or
-     * {@link #borrowObject borrowObject} after invoking this method on a pool
-     * will cause them to throw an {@link IllegalStateException}.
-     * </p>
-     * <p>
-     * Implementations should silently fail if not all resources can be freed.
-     * </p>
+     * @throws Exception if an instance cannot be returned to the pool
      */
-    @Override
-    void close();
+    void returnObject(K key, V obj) throws Exception;
 }
diff --git a/java/org/apache/tomcat/dbcp/pool2/ObjectPool.java b/java/org/apache/tomcat/dbcp/pool2/ObjectPool.java
index 6303245..ed94d93 100644
--- a/java/org/apache/tomcat/dbcp/pool2/ObjectPool.java
+++ b/java/org/apache/tomcat/dbcp/pool2/ObjectPool.java
@@ -60,6 +60,38 @@ import java.util.NoSuchElementException;
 public interface ObjectPool<T> extends Closeable {
 
     /**
+     * Creates an object using the {@link PooledObjectFactory factory} or other
+     * implementation dependent mechanism, passivate it, and then place it in
+     * the idle object pool. <code>addObject</code> is useful for "pre-loading"
+     * a pool with idle objects. (Optional operation).
+     *
+     * @throws Exception
+     *              when {@link PooledObjectFactory#makeObject} fails.
+     * @throws IllegalStateException
+     *              after {@link #close} has been called on this pool.
+     * @throws UnsupportedOperationException
+     *              when this pool cannot add new idle objects.
+     */
+    void addObject() throws Exception, IllegalStateException,
+            UnsupportedOperationException;
+
+    /**
+     * Calls {@link ObjectPool#addObject()} <code>count</code>
+     * number of times.
+     *
+     * @param count
+     *            the number of idle objects to add.
+     * @throws Exception
+     *             when {@link ObjectPool#addObject()} fails.
+     * @since 2.8.0
+     */
+    default void addObjects(final int count) throws Exception {
+        for (int i = 0; i < count; i++) {
+            addObject();
+        }
+    }
+
+    /**
      * Obtains an instance from this pool.
      * <p>
      * Instances returned from this method will have been either newly created
@@ -94,56 +126,36 @@ public interface ObjectPool<T> extends Closeable {
             IllegalStateException;
 
     /**
-     * Returns an instance to the pool. By contract, <code>obj</code>
-     * <strong>must</strong> have been obtained using {@link #borrowObject()} or
-     * a related method as defined in an implementation or sub-interface.
-     *
-     * @param obj a {@link #borrowObject borrowed} instance to be returned.
+     * Clears any objects sitting idle in the pool, releasing any associated
+     * resources (optional operation). Idle objects cleared must be
+     * {@link PooledObjectFactory#destroyObject(PooledObject)}.
      *
-     * @throws IllegalStateException
-     *              if an attempt is made to return an object to the pool that
-     *              is in any state other than allocated (i.e. borrowed).
-     *              Attempting to return an object more than once or attempting
-     *              to return an object that was never borrowed from the pool
-     *              will trigger this exception.
+     * @throws UnsupportedOperationException
+     *              if this implementation does not support the operation
      *
-     * @throws Exception if an instance cannot be returned to the pool
+     * @throws Exception if the pool cannot be cleared
      */
-    void returnObject(T obj) throws Exception;
+    void clear() throws Exception, UnsupportedOperationException;
 
     /**
-     * Invalidates an object from the pool.
+     * Closes this pool, and free any resources associated with it.
      * <p>
-     * By contract, <code>obj</code> <strong>must</strong> have been obtained
-     * using {@link #borrowObject} or a related method as defined in an
-     * implementation or sub-interface.
+     * Calling {@link #addObject} or {@link #borrowObject} after invoking this
+     * method on a pool will cause them to throw an {@link IllegalStateException}.
      * </p>
      * <p>
-     * This method should be used when an object that has been borrowed is
-     * determined (due to an exception or other problem) to be invalid.
+     * Implementations should silently fail if not all resources can be freed.
      * </p>
-     *
-     * @param obj a {@link #borrowObject borrowed} instance to be disposed.
-     *
-     * @throws Exception if the instance cannot be invalidated
      */
-    void invalidateObject(T obj) throws Exception;
+    @Override
+    void close();
 
     /**
-     * Creates an object using the {@link PooledObjectFactory factory} or other
-     * implementation dependent mechanism, passivate it, and then place it in
-     * the idle object pool. <code>addObject</code> is useful for "pre-loading"
-     * a pool with idle objects. (Optional operation).
-     *
-     * @throws Exception
-     *              when {@link PooledObjectFactory#makeObject} fails.
-     * @throws IllegalStateException
-     *              after {@link #close} has been called on this pool.
-     * @throws UnsupportedOperationException
-     *              when this pool cannot add new idle objects.
+     * Returns the number of instances currently borrowed from this pool. Returns
+     * a negative value if this information is not available.
+     * @return the number of instances currently borrowed from this pool.
      */
-    void addObject() throws Exception, IllegalStateException,
-            UnsupportedOperationException;
+    int getNumActive();
 
     /**
      * Returns the number of instances currently idle in this pool. This may be
@@ -155,34 +167,38 @@ public interface ObjectPool<T> extends Closeable {
     int getNumIdle();
 
     /**
-     * Returns the number of instances currently borrowed from this pool. Returns
-     * a negative value if this information is not available.
-     * @return the number of instances currently borrowed from this pool.
-     */
-    int getNumActive();
-
-    /**
-     * Clears any objects sitting idle in the pool, releasing any associated
-     * resources (optional operation). Idle objects cleared must be
-     * {@link PooledObjectFactory#destroyObject(PooledObject)}.
+     * Invalidates an object from the pool.
+     * <p>
+     * By contract, <code>obj</code> <strong>must</strong> have been obtained
+     * using {@link #borrowObject} or a related method as defined in an
+     * implementation or sub-interface.
+     * </p>
+     * <p>
+     * This method should be used when an object that has been borrowed is
+     * determined (due to an exception or other problem) to be invalid.
+     * </p>
      *
-     * @throws UnsupportedOperationException
-     *              if this implementation does not support the operation
+     * @param obj a {@link #borrowObject borrowed} instance to be disposed.
      *
-     * @throws Exception if the pool cannot be cleared
+     * @throws Exception if the instance cannot be invalidated
      */
-    void clear() throws Exception, UnsupportedOperationException;
+    void invalidateObject(T obj) throws Exception;
 
     /**
-     * Closes this pool, and free any resources associated with it.
-     * <p>
-     * Calling {@link #addObject} or {@link #borrowObject} after invoking this
-     * method on a pool will cause them to throw an {@link IllegalStateException}.
-     * </p>
-     * <p>
-     * Implementations should silently fail if not all resources can be freed.
-     * </p>
+     * Returns an instance to the pool. By contract, <code>obj</code>
+     * <strong>must</strong> have been obtained using {@link #borrowObject()} or
+     * a related method as defined in an implementation or sub-interface.
+     *
+     * @param obj a {@link #borrowObject borrowed} instance to be returned.
+     *
+     * @throws IllegalStateException
+     *              if an attempt is made to return an object to the pool that
+     *              is in any state other than allocated (i.e. borrowed).
+     *              Attempting to return an object more than once or attempting
+     *              to return an object that was never borrowed from the pool
+     *              will trigger this exception.
+     *
+     * @throws Exception if an instance cannot be returned to the pool
      */
-    @Override
-    void close();
+    void returnObject(T obj) throws Exception;
 }
diff --git a/java/org/apache/tomcat/dbcp/pool2/PoolUtils.java b/java/org/apache/tomcat/dbcp/pool2/PoolUtils.java
index 2494351..08ae83c 100644
--- a/java/org/apache/tomcat/dbcp/pool2/PoolUtils.java
+++ b/java/org/apache/tomcat/dbcp/pool2/PoolUtils.java
@@ -38,9 +38,9 @@ public final class PoolUtils {
 
     private static final String MSG_FACTOR_NEGATIVE = "factor must be positive.";
     private static final String MSG_MIN_IDLE = "minIdle must be non-negative.";
-    private static final String MSG_NULL_KEY = "key must not be null.";
+    static final String MSG_NULL_KEY = "key must not be null.";
     private static final String MSG_NULL_KEYED_POOL = "keyedPool must not be null.";
-    private static final String MSG_NULL_KEYS = "keys must not be null.";
+    static final String MSG_NULL_KEYS = "keys must not be null.";
     private static final String MSG_NULL_POOL = "pool must not be null.";
 
     /**
@@ -220,15 +220,15 @@ public final class PoolUtils {
      *             when {@link ObjectPool#addObject()} fails.
      * @throws IllegalArgumentException
      *             when <code>pool</code> is <code>null</code>.
+     * @deprecated Use {@link ObjectPool#addObjects(int)}.
      */
+    @Deprecated
     public static <T> void prefill(final ObjectPool<T> pool, final int count)
             throws Exception, IllegalArgumentException {
         if (pool == null) {
             throw new IllegalArgumentException(MSG_NULL_POOL);
         }
-        for (int i = 0; i < count; i++) {
-            pool.addObject();
-        }
+        pool.addObjects(count);
     }
 
     /**
@@ -248,19 +248,16 @@ public final class PoolUtils {
      * @throws IllegalArgumentException
      *             when <code>keyedPool</code> or <code>key</code> is
      *             <code>null</code>.
+     * @deprecated Use {@link KeyedObjectPool#addObjects(Object, int)}.
      */
+    @Deprecated
     public static <K, V> void prefill(final KeyedObjectPool<K, V> keyedPool,
             final K key, final int count) throws Exception,
             IllegalArgumentException {
         if (keyedPool == null) {
             throw new IllegalArgumentException(MSG_NULL_KEYED_POOL);
         }
-        if (key == null) {
-            throw new IllegalArgumentException(MSG_NULL_KEY);
-        }
-        for (int i = 0; i < count; i++) {
-            keyedPool.addObject(key);
-        }
+        keyedPool.addObjects(key, count);
     }
 
     /**
@@ -283,17 +280,16 @@ public final class PoolUtils {
      *             when <code>keyedPool</code>, <code>keys</code>, or any value
      *             in <code>keys</code> is <code>null</code>.
      * @see #prefill(KeyedObjectPool, Object, int)
+     * @deprecated Use {@link KeyedObjectPool#addObjects(Collection, int)}.
      */
+    @Deprecated
     public static <K, V> void prefill(final KeyedObjectPool<K, V> keyedPool,
             final Collection<K> keys, final int count) throws Exception,
             IllegalArgumentException {
         if (keys == null) {
             throw new IllegalArgumentException(MSG_NULL_KEYS);
         }
-        final Iterator<K> iter = keys.iterator();
-        while (iter.hasNext()) {
-            prefill(keyedPool, iter.next(), count);
-        }
+        keyedPool.addObjects(keys, count);
     }
 
     /**
diff --git a/java/org/apache/tomcat/dbcp/pool2/PooledObject.java b/java/org/apache/tomcat/dbcp/pool2/PooledObject.java
index 173a5d2..601c6c5 100644
--- a/java/org/apache/tomcat/dbcp/pool2/PooledObject.java
+++ b/java/org/apache/tomcat/dbcp/pool2/PooledObject.java
@@ -24,6 +24,7 @@ import java.util.Deque;
  * state, for the pooled objects.
  * <p>
  * Implementations of this class are required to be thread-safe.
+ * </p>
  *
  * @param <T> the type of object in the pool
  *
@@ -187,7 +188,7 @@ public interface PooledObject<T> extends Comparable<PooledObject<T>> {
      * @param requireFullStackTrace the new configuration setting for abandoned object logging
      * @since 2.7.0
      */
-    default void setRequireFullStackTrace(boolean requireFullStackTrace) {
+    default void setRequireFullStackTrace(final boolean requireFullStackTrace) {
         // noop
     }
 
diff --git a/java/org/apache/tomcat/dbcp/pool2/impl/DefaultEvictionPolicy.java b/java/org/apache/tomcat/dbcp/pool2/impl/DefaultEvictionPolicy.java
index fdacc6e..fc618a5 100644
--- a/java/org/apache/tomcat/dbcp/pool2/impl/DefaultEvictionPolicy.java
+++ b/java/org/apache/tomcat/dbcp/pool2/impl/DefaultEvictionPolicy.java
@@ -31,7 +31,9 @@ import org.apache.tomcat.dbcp.pool2.PooledObject;
  *     {@link GenericObjectPool#getSoftMinEvictableIdleTimeMillis()} /
  *     {@link GenericKeyedObjectPool#getSoftMinEvictableIdleTimeMillis()}
  * </ul>
+ * <p>
  * This class is immutable and thread-safe.
+ * </p>
  *
  * @param <T> the type of objects in the pool
  *
diff --git a/java/org/apache/tomcat/dbcp/pool2/impl/EvictionConfig.java b/java/org/apache/tomcat/dbcp/pool2/impl/EvictionConfig.java
index 49766f0..b124676 100644
--- a/java/org/apache/tomcat/dbcp/pool2/impl/EvictionConfig.java
+++ b/java/org/apache/tomcat/dbcp/pool2/impl/EvictionConfig.java
@@ -22,6 +22,7 @@ package org.apache.tomcat.dbcp.pool2.impl;
  * its own specific configuration attributes.
  * <p>
  * This class is immutable and thread-safe.
+ * </p>
  *
  * @since 2.0
  */
diff --git a/java/org/apache/tomcat/dbcp/pool2/impl/EvictionTimer.java b/java/org/apache/tomcat/dbcp/pool2/impl/EvictionTimer.java
index 46ded3f..e1ef59a 100644
--- a/java/org/apache/tomcat/dbcp/pool2/impl/EvictionTimer.java
+++ b/java/org/apache/tomcat/dbcp/pool2/impl/EvictionTimer.java
@@ -120,12 +120,9 @@ class EvictionTimer {
         public Thread newThread(final Runnable runnable) {
             final Thread thread = new Thread(null, runnable, "commons-pool-evictor-thread");
             thread.setDaemon(true); // POOL-363 - Required for applications using Runtime.addShutdownHook().
-            AccessController.doPrivileged(new PrivilegedAction<Void>() {
-                @Override
-                public Void run() {
-                    thread.setContextClassLoader(EvictorThreadFactory.class.getClassLoader());
-                    return null;
-                }
+            AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+                thread.setContextClassLoader(EvictorThreadFactory.class.getClassLoader());
+                return null;
             });
 
             return thread;
diff --git a/java/org/apache/tomcat/dbcp/pool2/impl/GenericKeyedObjectPool.java b/java/org/apache/tomcat/dbcp/pool2/impl/GenericKeyedObjectPool.java
index 01dc542..796faa2 100644
--- a/java/org/apache/tomcat/dbcp/pool2/impl/GenericKeyedObjectPool.java
+++ b/java/org/apache/tomcat/dbcp/pool2/impl/GenericKeyedObjectPool.java
@@ -50,10 +50,12 @@ import org.apache.tomcat.dbcp.pool2.PooledObjectState;
  * {@link #borrowObject borrowObject} methods. Each time a new key value is
  * provided to one of these methods, a sub-new pool is created under the given
  * key to be managed by the containing <code>GenericKeyedObjectPool.</code>
+ * </p>
  * <p>
  * Note that the current implementation uses a ConcurrentHashMap which uses
  * equals() to compare keys.
  * This means that distinct instance keys must be distinguishable using equals.
+ * </p>
  * <p>
  * Optionally, one may configure the pool to examine and possibly evict objects
  * as they sit idle in the pool and to ensure that a minimum number of idle
@@ -62,12 +64,15 @@ import org.apache.tomcat.dbcp.pool2.PooledObjectState;
  * configuring this optional feature. Eviction runs contend with client threads
  * for access to objects in the pool, so if they run too frequently performance
  * issues may result.
+ * </p>
  * <p>
  * Implementation note: To prevent possible deadlocks, care has been taken to
  * ensure that no call to a factory method will occur within a synchronization
  * block. See POOL-125 and DBCP-44 for more information.
+ * </p>
  * <p>
  * This class is intended to be thread-safe.
+ * </p>
  *
  * @see GenericObjectPool
  *
@@ -447,6 +452,11 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T>
 
         final ObjectDeque<T> objectDeque = poolMap.get(key);
 
+        if (objectDeque == null) {
+            throw new IllegalStateException(
+                    "No keyed pool found under the given key.");
+        }
+
         final PooledObject<T> p = objectDeque.getAllObjects().get(new IdentityWrapper<>(obj));
 
         if (p == null) {
@@ -1077,8 +1087,16 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T>
         final ObjectDeque<T> objectDeque = register(key);
 
         try {
-            final boolean isIdle = objectDeque.getIdleObjects().remove(toDestroy);
-
+            boolean isIdle;
+            synchronized(toDestroy) {
+                // Check idle state directly
+                isIdle = toDestroy.getState().equals(PooledObjectState.IDLE);
+                // If idle, not under eviction test, or always is true, remove instance,
+                // updating isIdle if instance is found in idle objects
+                if (isIdle || always) {
+                    isIdle = objectDeque.getIdleObjects().remove(toDestroy);
+                }
+            }
             if (isIdle || always) {
                 objectDeque.getAllObjects().remove(new IdentityWrapper<>(toDestroy.getObject()));
                 toDestroy.invalidate();
@@ -1151,10 +1169,9 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T>
      */
     private void deregister(final K k) {
         Lock lock = keyLock.readLock();
-        ObjectDeque<T> objectDeque;
         try {
             lock.lock();
-            objectDeque = poolMap.get(k);
+            final ObjectDeque<T> objectDeque = poolMap.get(k);
             final long numInterested = objectDeque.getNumInterested().decrementAndGet();
             if (numInterested == 0 && objectDeque.getCreateCount().get() == 0) {
                 // Potential to remove key
diff --git a/java/org/apache/tomcat/dbcp/pool2/impl/GenericObjectPool.java b/java/org/apache/tomcat/dbcp/pool2/impl/GenericObjectPool.java
index c72b701..b2a83dc 100644
--- a/java/org/apache/tomcat/dbcp/pool2/impl/GenericObjectPool.java
+++ b/java/org/apache/tomcat/dbcp/pool2/impl/GenericObjectPool.java
@@ -38,7 +38,8 @@ import org.apache.tomcat.dbcp.pool2.UsageTracking;
  * <p>
  * When coupled with the appropriate {@link PooledObjectFactory},
  * <code>GenericObjectPool</code> provides robust pooling functionality for
- * arbitrary objects.</p>
+ * arbitrary objects.
+ * </p>
  * <p>
  * Optionally, one may configure the pool to examine and possibly evict objects
  * as they sit idle in the pool and to ensure that a minimum number of idle
@@ -46,7 +47,8 @@ import org.apache.tomcat.dbcp.pool2.UsageTracking;
  * which runs asynchronously. Caution should be used when configuring this
  * optional feature. Eviction runs contend with client threads for access to
  * objects in the pool, so if they run too frequently performance issues may
- * result.</p>
+ * result.
+ * </p>
  * <p>
  * The pool can also be configured to detect and remove "abandoned" objects,
  * i.e. objects that have been checked out of the pool but neither used nor
@@ -59,13 +61,16 @@ import org.apache.tomcat.dbcp.pool2.UsageTracking;
  * their last use will be queried
  * using the <code>getLastUsed</code> method on that interface; otherwise
  * abandonment is determined by how long an object has been checked out from
- * the pool.</p>
+ * the pool.
+ * </p>
  * <p>
  * Implementation note: To prevent possible deadlocks, care has been taken to
  * ensure that no call to a factory method will occur within a synchronization
- * block. See POOL-125 and DBCP-44 for more information.</p>
+ * block. See POOL-125 and DBCP-44 for more information.
+ * </p>
  * <p>
- * This class is intended to be thread-safe.</p>
+ * This class is intended to be thread-safe.
+ * </p>
  *
  * @see GenericKeyedObjectPool
  *
@@ -576,6 +581,11 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
             } catch (final Exception e) {
                 swallowException(e);
             }
+            try {
+                ensureIdle(1, false);
+            } catch (final Exception e) {
+                swallowException(e);
+            }
         } else {
             if (getLifo()) {
                 idleObjects.addFirst(p);
@@ -931,15 +941,6 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
             destroyedCount.incrementAndGet();
             createCount.decrementAndGet();
         }
-
-        if (idleObjects.isEmpty() && idleObjects.hasTakeWaiters()) {
-            // POOL-356.
-            // In case there are already threads waiting on something in the pool
-            // (e.g. idleObjects.takeFirst(); then we need to provide them a fresh instance.
-            // Otherwise they will be stuck forever (or until timeout)
-            final PooledObject<T> freshPooled = create();
-            idleObjects.put(freshPooled);
-        }
     }
 
     @Override
diff --git a/java/org/apache/tomcat/dbcp/pool2/impl/InterruptibleReentrantLock.java b/java/org/apache/tomcat/dbcp/pool2/impl/InterruptibleReentrantLock.java
index 5a51b92..b539aed 100644
--- a/java/org/apache/tomcat/dbcp/pool2/impl/InterruptibleReentrantLock.java
+++ b/java/org/apache/tomcat/dbcp/pool2/impl/InterruptibleReentrantLock.java
@@ -26,6 +26,7 @@ import java.util.concurrent.locks.ReentrantLock;
  * class is intended for internal use only.
  * <p>
  * This class is intended to be thread-safe.
+ * </p>
  *
  * @since 2.0
  */
diff --git a/java/org/apache/tomcat/dbcp/pool2/impl/LinkedBlockingDeque.java b/java/org/apache/tomcat/dbcp/pool2/impl/LinkedBlockingDeque.java
index be92f91..75e925e 100644
--- a/java/org/apache/tomcat/dbcp/pool2/impl/LinkedBlockingDeque.java
+++ b/java/org/apache/tomcat/dbcp/pool2/impl/LinkedBlockingDeque.java
@@ -34,6 +34,7 @@ import java.util.concurrent.locks.Condition;
  * is equal to {@link Integer#MAX_VALUE}.  Linked nodes are
  * dynamically created upon each insertion unless this would bring the
  * deque above capacity.
+ * </p>
  *
  * <p>Most operations run in constant time (ignoring time spent
  * blocking).  Exceptions include {@link #remove(Object) remove},
@@ -41,14 +42,17 @@ import java.util.concurrent.locks.Condition;
  * #removeLastOccurrence removeLastOccurrence}, {@link #contains
  * contains}, {@link #iterator iterator.remove()}, and the bulk
  * operations, all of which run in linear time.
+ * </p>
  *
  * <p>This class and its iterator implement all of the
  * <em>optional</em> methods of the {@link Collection} and {@link
  * Iterator} interfaces.
+ * </p>
  *
  * <p>This class is a member of the
  * <a href="{@docRoot}/../technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
+ * </p>
  *
  * @param <E> the type of elements held in this collection
  *
diff --git a/java/org/apache/tomcat/dbcp/pool2/impl/SecurityManagerCallStack.java b/java/org/apache/tomcat/dbcp/pool2/impl/SecurityManagerCallStack.java
index 032a558..14283d6 100644
--- a/java/org/apache/tomcat/dbcp/pool2/impl/SecurityManagerCallStack.java
+++ b/java/org/apache/tomcat/dbcp/pool2/impl/SecurityManagerCallStack.java
@@ -52,12 +52,7 @@ public class SecurityManagerCallStack implements CallStack {
     public SecurityManagerCallStack(final String messageFormat, final boolean useTimestamp) {
         this.messageFormat = messageFormat;
         this.dateFormat = useTimestamp ? new SimpleDateFormat(messageFormat) : null;
-        this.securityManager = AccessController.doPrivileged(new PrivilegedAction<PrivateSecurityManager>() {
-            @Override
-            public PrivateSecurityManager run() {
-                return new PrivateSecurityManager();
-            }
-        });
+        this.securityManager = AccessController.doPrivileged((PrivilegedAction<PrivateSecurityManager>) () -> new PrivateSecurityManager());
     }
 
     @Override
diff --git a/java/org/apache/tomcat/dbcp/pool2/impl/SoftReferenceObjectPool.java b/java/org/apache/tomcat/dbcp/pool2/impl/SoftReferenceObjectPool.java
index 61741be..e417b48 100644
--- a/java/org/apache/tomcat/dbcp/pool2/impl/SoftReferenceObjectPool.java
+++ b/java/org/apache/tomcat/dbcp/pool2/impl/SoftReferenceObjectPool.java
@@ -32,6 +32,7 @@ import org.apache.tomcat.dbcp.pool2.PooledObjectFactory;
  * {@link org.apache.tomcat.dbcp.pool2.ObjectPool}.
  * <p>
  * This class is intended to be thread-safe.
+ * </p>
  *
  * @param <T>
  *            Type of element pooled in this pool.
@@ -185,6 +186,8 @@ public class SoftReferenceObjectPool<T> extends BaseObjectPool<T> {
      *
      * @param obj
      *            instance to return to the pool
+     * @throws IllegalArgumentException
+     *            if obj is not currently part of this pool
      */
     @Override
     public synchronized void returnObject(final T obj) throws Exception {
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 66e4c0e..c1d9427 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -216,6 +216,10 @@
         Update the internal fork of Apache Commons FileUpload to 2317552
         (2019-12-06, 2.0-SNAPSHOT). Refactoring. (markt)
       </add>
+      <add>
+        Update the internal fork of Apache Commons Pool 2 to 6092f92 (2019-12-06,
+        2.8.0-SNAPSHOT). Clean-up and minor refactoring. (markt)
+      </add>
     </changelog>
   </subsection>
 </section>


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