[ https://issues.apache.org/jira/browse/POOL-326?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16915347#comment-16915347 ]
Phil Steitz edited comment on POOL-326 at 8/26/19 3:46 AM: ----------------------------------------------------------- I don't think we fully fixed this problem. I am now getting sporadic NPEs in returnObject when running soak tests with the following config: maxTotal = 50, maxIdlePerKey=10, minIdlePerKey=5, maxTotalPerKey=10, maxWait=-1 Evictor runs every 2 seconds, 3 tests, 1 second idle timeout. Validation is off except while idle. The factory is set to add latency in make and destroy and there are 100 threads running concurrently. This setup (and the way reuseCapacity works) generates a lot of object churn. For example, one run that hit the NPE had these final stats: borrowedCount=21261, returnedCount=21222, createdCount=13822, destroyedCount=13806, destroyedByEvictorCount=9. The NPE happens when returnObject(key) dereferences the ObjectDeque returned by {code:java} poolMap.get(key){code} I can make the NPE go away by adding the condition allObjects.isEmpty() to the test before removing a key in deregister, but what is bugging me is I can't figure out how it is happening. All of my attempts thus far at a simple unit test making this happen or an explanation for how it can happen have failed. The lock used in register / deregister should make it impossible for a key to be eliminated while there is an instance checked out. Somehow createCount is getting zeroed while there is an instance checked out. was (Author: psteitz): I don't think we fully fixed this problem. I am now getting sporadic NPEs when running soak tests with the following config: maxTotal = 50, maxIdlePerKey=10, minIdlePerKey=5, maxTotalPerKey=10, maxWait=-1 Evictor runs every 2 seconds, 3 tests, 1 second idle timeout. Validation is off except while idle. The factory is set to add latency in make and destroy and there are 100 threads running concurrently. This setup (and the way reuseCapacity works) generates a lot of object churn. For example, one run that hit the NPE had these final stats: borrowedCount=21261, returnedCount=21222, createdCount=13822, destroyedCount=13806, destroyedByEvictorCount=9. I can make the NPE go away by adding the condition allObjects.isEmpty() to the test before removing a key, but what is bugging me is I can't figure out how it is happening. All of my attempts thus far at a simple unit test making this happen or an explanation for how it can happen have failed. The lock used in register / deregister should make it impossible for a key to be eliminated while there is an instance checked out. Somehow createCount is getting zeroed while there is an instance checked out. > Threading issue, NullPointerException and IllegalStateException in > GenericKeyedObjectPool > ----------------------------------------------------------------------------------------- > > Key: POOL-326 > URL: https://issues.apache.org/jira/browse/POOL-326 > Project: Commons Pool > Issue Type: Bug > Affects Versions: 2.4.2 > Reporter: Chris Allison > Priority: Major > Fix For: 2.6.1 > > Attachments: ObjectPoolIssue.java, pool-326.patch > > > I'll included a test to help reproduce this issue. Take a look at the > embedded comments as it's extremely difficult to reproduce. I've seen the > provided test show the failure on more than one PC so I believe it will show > the problem. > Example stack trace for error on return: > java.util.concurrent.ExecutionException: java.lang.NullPointerException > at java.util.concurrent.FutureTask.report(FutureTask.java:122) > at java.util.concurrent.FutureTask.get(FutureTask.java:192) > at threading_pool.ObjectPoolIssue.run(ObjectPoolIssue.java:63) > at threading_pool.ObjectPoolIssue.main(ObjectPoolIssue.java:23) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.lang.reflect.Method.invoke(Method.java:498) > at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) > Caused by: java.lang.NullPointerException > at > org.apache.commons.pool2.impl.GenericKeyedObjectPool.returnObject(GenericKeyedObjectPool.java:474) > at threading_pool.ObjectPoolIssue$Task.call(ObjectPoolIssue.java:112) > at java.util.concurrent.FutureTask.run(FutureTask.java:266) > at > java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) > at > java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) > at java.lang.Thread.run(Thread.java:745) > Example stack trace for error on borrow: > java.util.concurrent.ExecutionException: java.lang.NullPointerException > at java.util.concurrent.FutureTask.report(FutureTask.java:122) > at java.util.concurrent.FutureTask.get(FutureTask.java:192) > at threading_pool.ObjectPoolIssue.run(ObjectPoolIssue.java:63) > at threading_pool.ObjectPoolIssue.main(ObjectPoolIssue.java:23) > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) > at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.lang.reflect.Method.invoke(Method.java:498) > at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) > Caused by: java.lang.NullPointerException > at > org.apache.commons.pool2.impl.GenericKeyedObjectPool.deregister(GenericKeyedObjectPool.java:1146) > at > org.apache.commons.pool2.impl.GenericKeyedObjectPool.borrowObject(GenericKeyedObjectPool.java:438) > at > org.apache.commons.pool2.impl.GenericKeyedObjectPool.borrowObject(GenericKeyedObjectPool.java:279) > at threading_pool.ObjectPoolIssue$Task.call(ObjectPoolIssue.java:108) > at java.util.concurrent.FutureTask.run(FutureTask.java:266) > at > java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) > at > java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) > at java.lang.Thread.run(Thread.java:745) -- This message was sent by Atlassian Jira (v8.3.2#803003)