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.