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

ASF GitHub Bot commented on JENA-1260:
--------------------------------------

GitHub user der opened a pull request:

    https://github.com/apache/jena/pull/193

    JENA-1260

    Deterministic testcase for #JENA-1260. Tests the entangling of 
TransitiveEngine state by careful prodding of a TransitiveReasoner (avoiding 
full RDFS machinery) - fails prior to the fix for JENA-1260 and passes 
afterwards.

You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/der/jena JENA-1260

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/jena/pull/193.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #193
    
----
commit a424b2191a8c3a72a8a2ef7fd922d3516755d762
Author: der <d...@epimorphics.com>
Date:   2016-11-16T14:37:52Z

    Deterministic testcase for JENA-1260

----


> NullPointerException when using an inferencing model under multithreaded load 
> with query and delete
> ---------------------------------------------------------------------------------------------------
>
>                 Key: JENA-1260
>                 URL: https://issues.apache.org/jira/browse/JENA-1260
>             Project: Apache Jena
>          Issue Type: Bug
>          Components: Jena
>    Affects Versions: Jena 3.0.0
>            Reporter: Stephen Owens
>            Assignee: Dave Reynolds
>         Attachments: TransitiveEngineFailureTest.java
>
>
> {noformat}
> java.lang.NullPointerException
>       at java.util.HashSet.contains(HashSet.java:203)
>       at 
> org.apache.jena.reasoner.transitiveReasoner.TransitiveEngine.triage(TransitiveEngine.java:194)
>       at 
> org.apache.jena.reasoner.transitiveReasoner.TransitiveEngine.add(TransitiveEngine.java:234)
>       at 
> org.apache.jena.reasoner.rulesys.FBRuleInfGraph.prepare(FBRuleInfGraph.java:431)
>       at 
> org.apache.jena.reasoner.BaseInfGraph.requirePrepared(BaseInfGraph.java:530)
>       at 
> org.apache.jena.reasoner.rulesys.FBRuleInfGraph.findWithContinuation(FBRuleInfGraph.java:557)
>       at 
> org.apache.jena.reasoner.rulesys.FBRuleInfGraph.graphBaseFind(FBRuleInfGraph.java:587)
>       at org.apache.jena.graph.impl.GraphBase.find(GraphBase.java:255)
>       at 
> org.apache.jena.sparql.engine.iterator.QueryIterTriplePattern$TripleMapper.<init>(QueryIterTriplePattern.java:75)
>       at 
> org.apache.jena.sparql.engine.iterator.QueryIterTriplePattern.nextStage(QueryIterTriplePattern.java:49)
>       at 
> org.apache.jena.sparql.engine.iterator.QueryIterRepeatApply.makeNextStage(QueryIterRepeatApply.java:108)
>       at 
> org.apache.jena.sparql.engine.iterator.QueryIterRepeatApply.hasNextBinding(QueryIterRepeatApply.java:65)
>       at 
> org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:111)
>       at 
> org.apache.jena.sparql.engine.iterator.QueryIterBlockTriples.hasNextBinding(QueryIterBlockTriples.java:63)
>       at 
> org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:111)
>       at 
> org.apache.jena.sparql.engine.iterator.QueryIteratorWrapper.hasNextBinding(QueryIteratorWrapper.java:39)
>       at 
> org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:111)
>       at 
> org.apache.jena.sparql.engine.iterator.QueryIteratorWrapper.hasNextBinding(QueryIteratorWrapper.java:39)
>       at 
> org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:111)
>       at org.apache.jena.atlas.iterator.Iter$4.hasNext(Iter.java:264)
>       at 
> org.apache.jena.ext.com.google.common.collect.Iterators$5.hasNext(Iterators.java:547)
>       at 
> org.apache.jena.test.TransitiveEngineFailureTest$FailureTask.execQuery(TransitiveEngineFailureTest.java:109)
>       at 
> org.apache.jena.test.TransitiveEngineFailureTest$FailureTask.call(TransitiveEngineFailureTest.java:75)
>       at 
> org.apache.jena.test.TransitiveEngineFailureTest$FailureTask.call(TransitiveEngineFailureTest.java:1)
>       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)
> {noformat}
> This failure is due to the 
> {{org.apache.jena.reasoner.transitiveReasoner.TransitiveEngine}} class 
> declaring the {{subClassAliases}}
> member variable (of type HashSet<Node>) as static. The prepare method 
> re-creates this shared variable whenever {{isPrepared}}
> is false:
> {noformat}
>     private void prepare() {
>         if (isPrepared) return;
>         subClassAliases = new HashSet<>();
>         . . .
>         isPrepared = true;
>     }
> {noformat}
> In particular, the static {{subClassAliases}} variable will be re-created 
> whenever a {{TransitiveEngine}} object is created
> ({{isPrepared}} is false at creation time). Note that HashSet is neither 
> thread-safe nor being accessed in a thread-safe manner.
> The combination of attempting to remove triples from the model and attempting 
> to execute queries on the model leads
> to unsafe accesses to {{subClassAliases}}, which eventually leads to a null 
> pointer exception.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to