commons-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Phil Steitz (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (POOL-326) Threading issue, NullPointerException and IllegalStateException in GenericKeyedObjectPool
Date Sun, 28 May 2017 16:28:04 GMT

    [ https://issues.apache.org/jira/browse/POOL-326?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16027856#comment-16027856
] 

Phil Steitz commented on POOL-326:
----------------------------------

Nice job on the test case and bug report, Chris!

Looks like you are using git head, right, Gary?  I have also verified that the problem exists
with both the 2.4.2 release jar and git head as of fc68e1ba783b49df82e27fc88f4cb8819aa0b0c0.

I am not sure, but I suspect at least the borrowObject NPE might be caused by the following
scenario (line numbers from git head)

1. Thread 1 enters deregister and the conditions are met so it progresses to line 1178 where
it waits for a write lock.
2. Thread 2 enters deregister and decrements numInterested, now to -1.
3. Thread 3 (a borrower) enters and exits register, but numInterested just gets incremented
back to 0.
4. Thread 1 completes (second test succeeding), killing the deque.
5. Thread 3 enters deregister and gets NPE

I added some instrumentation to the test code and it looks like the npe on borrow-deregister
is occurring when the pool is out of capacity and numActive and numIdle for the key under
which the borrow request is made are both 0.  Strictly speaking, you can't really tell from
instrumentation because between the exception and the catch other threads could be changing
those stats.  I get the same thing repeatedly, though.

When I modify deregister to work like register does - immediately acquire a read lock and
then escalate if needed to a write lock - the test code does not raise NPEs or ISEs.  Attached
is a patch with that change.  It should be carefully reviewed and performance-tested before
being applied.  I doubt the performance hit would be measurable, but it is adding some lock
contention.

> 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
>         Attachments: ObjectPoolIssue.java
>
>
> 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
(v6.3.15#6346)

Mime
View raw message