[
https://issues.apache.org/jira/browse/JENA-399?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13583795#comment-13583795
]
Rob Vesse commented on JENA-399:
--------------------------------
The issue looks to be a race condition in the prepare() code for InferenceModel
which means if multiple threads try to query the model multiple threads may
call into prepare() at the same time resulting in the
ConcurrentModificationException you experience and I have been able to
reproduce.
I am working on a fix for this and will likely have something that you can test
against tomorrow
> Concurrent execution of SPARQL CONSTRUCT statements against the same
> Inference 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, Reasoners
> Affects Versions: Jena 2.10.0
> Reporter: Stephen Owens
> Labels: InferenceModel
> 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