Stephen Owens created JENA-399:
----------------------------------

             Summary: Concurrent execution of SPARQL CONSTRUCT statements 
against the same model leads to a ConcurrentModificationException
                 Key: JENA-399
                 URL: https://issues.apache.org/jira/browse/JENA-399
             Project: Apache Jena
          Issue Type: Bug
          Components: ARQ
    Affects Versions: Jena 2.10.0
            Reporter: Stephen Owens
         Attachments: JenaReadLockFailureTest.java

Read lock seems to be insufficient for a construct SPARQL query against a model 
in a multi-threaded situation. See the attached test case for details. 

The ConcurrentModificationException is thrown from: 
LPTopGoalIterator.checkClosed
 in com.hp.hpl.jena.reasoner.rulesys.impl.LPTopGoalIterator

Here is a stack trace that shows a path from QueryExecutionBase.
execConstruct() to LPBRuleEngine.checkSafeToUpdate():

LPBRuleEngine.checkSafeToUpdate() line: 223    
LPBRuleEngine.deleteAllRules() line: 155    
RDFSRuleInfGraph(FBRuleInfGraph).prepare() line: 460    
RDFSRuleInfGraph(FBRuleInfGraph).findWithContinuation(TriplePattern, Finder) 
line: 573    
RDFSRuleInfGraph(FBRuleInfGraph).graphBaseFind(Node, Node, Node) line: 605    
RDFSRuleInfGraph(GraphBase).find(Node, Node, Node) line: 287    
QueryIterTriplePattern$TripleMapper.<init>(Binding, Triple, ExecutionContext) 
line: 80    
QueryIterTriplePattern.nextStage(Binding) line: 53    
QueryIterTriplePattern(QueryIterRepeatApply).makeNextStage() line: 115    
QueryIterTriplePattern(QueryIterRepeatApply).hasNextBinding() line: 67    
QueryIterTriplePattern(QueryIteratorBase).hasNext() line: 113    
QueryIterBlockTriples.hasNextBinding() line: 64    
QueryIterBlockTriples(QueryIteratorBase).hasNext() line: 113    
QueryIterOptionalIndex(QueryIterRepeatApply).makeNextStage() line: 108    
QueryIterOptionalIndex(QueryIterRepeatApply).hasNextBinding() line: 67    
QueryIterOptionalIndex(QueryIteratorBase).hasNext() line: 113    
QueryIteratorCheck(QueryIteratorWrapper).hasNextBinding() line: 40    
QueryIteratorCheck(QueryIteratorBase).hasNext() line: 113    
QueryIteratorCloseable(QueryIteratorWrapper).hasNextBinding() line: 40    
QueryIteratorCloseable(QueryIteratorBase).hasNext() line: 113    
Iter$5.hasNext() line: 335    
QueryExecutionBase.execConstruct(Model) line: 225    
QueryExecutionBase.execConstruct() line: 201    

This is a problem because LPBRuleEngine.checkSafeToUpdate() closes all 
LPTopGoalIterator iterators, some of which are in the middle of processing:

    public void checkSafeToUpdate() {
        if (!activeInterpreters.isEmpty()) {
            ArrayList<LPInterpreterContext> toClose = new 
ArrayList<LPInterpreterContext>();
            for (Iterator<LPInterpreter> i = activeInterpreters.iterator(); 
i.hasNext(); ) {
                LPInterpreter interpreter = i.next();
                if (interpreter.getContext() instanceof LPTopGoalIterator) {
                    toClose.add(interpreter.getContext());
                }
            }
            for (Iterator<LPInterpreterContext> i = toClose.iterator(); 
i.hasNext(); ) {
                ((LPTopGoalIterator)i.next()).close();
            }
        }
    }


--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to