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

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-pool.git


The following commit(s) were added to refs/heads/master by this push:
     new 23afbe7a [POOL-405] NullPointerException at 
org.apache.commons.pool2.impl.GenericKeyedObjectPool.invalidateObject(GenericKeyedObjectPool.java:1343)
23afbe7a is described below

commit 23afbe7a316a6e27796823701ecb41737657cfa4
Author: Gary Gregory <[email protected]>
AuthorDate: Thu Apr 21 10:40:29 2022 -0400

    [POOL-405] NullPointerException at
    
org.apache.commons.pool2.impl.GenericKeyedObjectPool.invalidateObject(GenericKeyedObjectPool.java:1343)
---
 src/changes/changes.xml                            |  3 +++
 .../commons/pool2/impl/GenericKeyedObjectPool.java |  2 +-
 .../pool2/impl/TestGenericKeyedObjectPool.java     | 26 +++++++++++++++++-----
 3 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index e0bbeb5d..1a3e1373 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -60,6 +60,9 @@ The <action> type attribute can be add,update,fix,remove.
     <action dev="ggregory" type="fix" due-to="Gary Gregory" issue="POOL-269">
       Use generic exceptions instead of java.lang.Exception.
     </action>       
+    <action dev="ggregory" type="fix" due-to="Gary Gregory" issue="POOL-405">
+      NullPointerException at 
org.apache.commons.pool2.impl.GenericKeyedObjectPool.invalidateObject(GenericKeyedObjectPool.java:1343).
+    </action>       
     <!-- ADD -->
     <action dev="ggregory" type="add" due-to="Gary Gregory">
       Add PooledObject.getFullDuration().
diff --git 
a/src/main/java/org/apache/commons/pool2/impl/GenericKeyedObjectPool.java 
b/src/main/java/org/apache/commons/pool2/impl/GenericKeyedObjectPool.java
index 81aeb837..4418afc9 100644
--- a/src/main/java/org/apache/commons/pool2/impl/GenericKeyedObjectPool.java
+++ b/src/main/java/org/apache/commons/pool2/impl/GenericKeyedObjectPool.java
@@ -1340,7 +1340,7 @@ public class GenericKeyedObjectPool<K, T, E extends 
Exception> extends BaseGener
     @Override
     public void invalidateObject(final K key, final T obj, final DestroyMode 
destroyMode) throws E {
         final ObjectDeque<T> objectDeque = poolMap.get(key);
-        final PooledObject<T> p = objectDeque.getAllObjects().get(new 
IdentityWrapper<>(obj));
+        final PooledObject<T> p = objectDeque != null ? 
objectDeque.getAllObjects().get(new IdentityWrapper<>(obj)) : null;
         if (p == null) {
             throw new IllegalStateException(appendStats("Object not currently 
part of this pool"));
         }
diff --git 
a/src/test/java/org/apache/commons/pool2/impl/TestGenericKeyedObjectPool.java 
b/src/test/java/org/apache/commons/pool2/impl/TestGenericKeyedObjectPool.java
index 662884b8..7203abec 100644
--- 
a/src/test/java/org/apache/commons/pool2/impl/TestGenericKeyedObjectPool.java
+++ 
b/src/test/java/org/apache/commons/pool2/impl/TestGenericKeyedObjectPool.java
@@ -53,6 +53,7 @@ import javax.management.MBeanServer;
 import javax.management.ObjectName;
 
 import org.apache.commons.pool2.BaseKeyedPooledObjectFactory;
+import org.apache.commons.pool2.DestroyMode;
 import org.apache.commons.pool2.KeyedObjectPool;
 import org.apache.commons.pool2.KeyedPooledObjectFactory;
 import org.apache.commons.pool2.PooledObject;
@@ -65,6 +66,8 @@ import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.EnumSource;
 
 /**
  */
@@ -111,12 +114,12 @@ public class TestGenericKeyedObjectPool extends 
TestKeyedObjectPool {
      * Attempts to invalidate an object, swallowing IllegalStateException.
      */
     static class InvalidateThread implements Runnable {
-        
+
         private final String obj;
         private final KeyedObjectPool<String, String, Exception> pool;
         private final String key;
         private boolean done;
-        
+
         public InvalidateThread(final KeyedObjectPool<String, String, 
Exception> pool, final String key, final String obj) {
             this.obj = obj;
             this.pool = pool;
@@ -1013,7 +1016,6 @@ public class TestGenericKeyedObjectPool extends 
TestKeyedObjectPool {
         gkoPool.close();
     }
 
-
     /**
      * Test to make sure that clearOldest does not destroy instances that have 
been checked out.
      *
@@ -1050,6 +1052,7 @@ public class TestGenericKeyedObjectPool extends 
TestKeyedObjectPool {
         }
     }
 
+
     /**
        * POOL-391 Verify that when clear(key) is called with reuseCapacity 
true,
        * capacity freed is reused and allocated to most loaded pools.
@@ -1544,7 +1547,6 @@ public class TestGenericKeyedObjectPool extends 
TestKeyedObjectPool {
         checkEvictorVisiting(false);
     }
 
-
     @Test
     @Timeout(value = 60000, unit = TimeUnit.MILLISECONDS)
     public void testExceptionInValidationDuringEviction() throws Exception {
@@ -1561,6 +1563,7 @@ public class TestGenericKeyedObjectPool extends 
TestKeyedObjectPool {
         assertEquals(0, gkoPool.getNumIdle());
     }
 
+
     @Test
     @Timeout(value = 60000, unit = TimeUnit.MILLISECONDS)
     public void testExceptionOnActivateDuringBorrow() throws Exception {
@@ -1665,7 +1668,7 @@ public class TestGenericKeyedObjectPool extends 
TestKeyedObjectPool {
     public void testGetStatsString() {
         assertNotNull((gkoPool.getStatsString()));
     }
-    
+
     /**
      * Verify that threads waiting on a depleted pool get served when a 
checked out object is
      * invalidated.
@@ -1697,7 +1700,7 @@ public class TestGenericKeyedObjectPool extends 
TestKeyedObjectPool {
             }
         }
     }
-    
+
     @Test
     public void testInvalidateFreesCapacityForOtherKeys() throws Exception {
         gkoPool.setMaxTotal(1);
@@ -1711,6 +1714,17 @@ public class TestGenericKeyedObjectPool extends 
TestKeyedObjectPool {
         assertFalse(borrower.isAlive());
     }
 
+    @Test
+    public void testInvalidateMissingKey() throws Exception {
+        assertThrows(IllegalStateException.class, () -> 
gkoPool.invalidateObject("UnknownKey", "Ignored"));
+    }
+
+    @ParameterizedTest
+    @EnumSource(DestroyMode.class)
+    public void testInvalidateMissingKeyForDestroyMode(final DestroyMode 
destroyMode) throws Exception {
+        assertThrows(IllegalStateException.class, () -> 
gkoPool.invalidateObject("UnknownKey", "Ignored", destroyMode));
+    }
+
     /**
      * Verify that threads blocked waiting on a depleted pool get served when 
a checked out instance
      * is invalidated.

Reply via email to