[ 
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)

Reply via email to