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