Skip to content

Instantly share code, notes, and snippets.

@fkleedorfer
Created January 3, 2018 16:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fkleedorfer/4c4da3ccc21132490b4990f960a8ca2f to your computer and use it in GitHub Desktop.
Save fkleedorfer/4c4da3ccc21132490b4990f960a8ca2f to your computer and use it in GitHub Desktop.
ConcurrentModificationException for Jena 3.5.0 SELECT query
package won.utils.agreement;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import org.apache.commons.io.Charsets;
import org.apache.commons.io.IOUtils;
import org.apache.jena.query.Dataset;
import org.apache.jena.query.DatasetFactory;
import org.apache.jena.query.Query;
import org.apache.jena.query.QueryExecution;
import org.apache.jena.query.QueryExecutionFactory;
import org.apache.jena.query.QueryFactory;
import org.apache.jena.query.QuerySolution;
import org.apache.jena.query.ReadWrite;
import org.apache.jena.query.ResultSet;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.RDFNode;
import org.apache.jena.rdf.model.Statement;
import org.apache.jena.rdf.model.impl.PropertyImpl;
import org.apache.jena.rdf.model.impl.StatementImpl;
public class AgreementFunction {
private static final String AGREEMENT_SUFFIX = "";
private String queryString;
private static String queryFile = "/agreement/query.sq";
public AgreementFunction() {
InputStream is = AgreementFunction.class.getResourceAsStream(queryFile);
StringWriter writer = new StringWriter();
try {
IOUtils.copy(is, writer, Charsets.UTF_8);
} catch (IOException e) {
throw new IllegalStateException("Could not read query file from classpath location " + queryFile, e);
}
this.queryString = writer.toString();
}
public Dataset applyAgreementFunction(Dataset conversationDataset){
conversationDataset.begin(ReadWrite.READ);
Dataset result = DatasetFactory.createGeneral();
result.begin(ReadWrite.WRITE);
Query query = QueryFactory.create(queryString);
try (QueryExecution queryExecution = QueryExecutionFactory.create(query, conversationDataset)) {
ResultSet resultSet = queryExecution.execSelect();
RDFNode currentAgreement = null;
Model currentAgreementContent = ModelFactory.createDefaultModel();
System.out.println("result");
while (resultSet.hasNext()) {
QuerySolution solution = resultSet.next();
RDFNode agreementNode = solution.get("acc");
if (currentAgreement == null) {
//first solution: remember uri of first agreement
currentAgreement = agreementNode;
} else {
//at least 2nd solution: if the agreement uri has changed, our current agreement has been
//processed. add the model containing its triples to the dataset under
//the currentAgreement URI and prepare a new empty model for the next agreement
if (!currentAgreement.equals(agreementNode)) {
//we have seen all triples of currentAgreement
result.addNamedModel(currentAgreement.asResource().getURI(), currentAgreementContent);
currentAgreementContent = ModelFactory.createDefaultModel();
}
currentAgreement = agreementNode;
}
//add current triple into currentAgreementModel
RDFNode s = solution.get("s");
RDFNode p = solution.get("p");
RDFNode o = solution.get("o");
Statement newStatement = new StatementImpl(s.asResource(), new PropertyImpl(p.asResource().getURI()), o);
currentAgreementContent.add(newStatement);
}
//add the last model
if (currentAgreement != null) {
result.addNamedModel(currentAgreement.asResource().getURI()+AGREEMENT_SUFFIX, currentAgreementContent);
}
return result;
} finally {
conversationDataset.commit();
result.commit();
}
}
}
@prefix msg: <http://purl.org/webofneeds/message#> .
@prefix conn: <https://localhost:8443/won/resource/connection/> .
@prefix woncrypt: <http://purl.org/webofneeds/woncrypt#> .
@prefix need: <https://localhost:8443/won/resource/need/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix cert: <http://www.w3.org/ns/auth/cert#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix agr: <http://purl.org/webofneeds/agreement#> .
@prefix local: <https://localhost:8443/won/resource/> .
@prefix sig: <http://icp.it-risk.iwvi.uni-koblenz.de/ontologies/signature.owl#> .
@prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> .
@prefix s: <http://schema.org/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix won: <http://purl.org/webofneeds/model#> .
@prefix ldp: <http://www.w3.org/ns/ldp#> .
@prefix event: <https://localhost:8443/won/resource/event/> .
@prefix sioc: <http://rdfs.org/sioc/ns#> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
<https://localhost:8443/won/resource/event/ow321nn1va6clfidc4s0#envelope-l74h> {
event:ow321nn1va6clfidc4s0
msg:hasPreviousMessage event:9fhq1ef81bw0vwps12c5 .
}
<https://localhost:8443/won/resource/event/557600936467257340#envelope-xg0i> {
event:557600936467257340
msg:hasPreviousMessage event:omh6mnwfqczgjimg3sch .
}
<https://localhost:8443/won/resource/event/5669098069340991000#data> {
event:5669098069340991000
msg:hasContent <https://localhost:8443/won/resource/event/5669098069340991000#content> .
}
<https://localhost:8443/won/resource/event/557600936467257340#content> {
event:557600936467257340
agr:proposes event:5669098069340991000 .
}
<https://localhost:8443/won/resource/event/nmnetfuihnx70r0do0id#envelope-4o4g> {
event:nmnetfuihnx70r0do0id
msg:hasPreviousMessage event:5669098069340991000 .
}
<https://localhost:8443/won/resource/event/ow321nn1va6clfidc4s0#content-1o90> {
event:ow321nn1va6clfidc4s0
agr:accepts event:557600936467257340 .
}
<https://localhost:8443/won/resource/event/9fhq1ef81bw0vwps12c5#envelope-u0yx> {
event:9fhq1ef81bw0vwps12c5
msg:hasPreviousMessage event:hp6hw2wa3bbww4wo8gfo .
}
<https://localhost:8443/won/resource/event/omh6mnwfqczgjimg3sch#envelope-b7qv> {
event:omh6mnwfqczgjimg3sch
msg:hasPreviousMessage event:krcmdz8802701wpzlzl8 .
}
<https://localhost:8443/won/resource/event/krcmdz8802701wpzlzl8#envelope-qdj9> {
event:krcmdz8802701wpzlzl8
msg:hasPreviousMessage event:nmnetfuihnx70r0do0id .
}
<https://localhost:8443/won/resource/event/hp6hw2wa3bbww4wo8gfo#envelope-gpzu> {
event:hp6hw2wa3bbww4wo8gfo
msg:hasCorrespondingRemoteMessage
event:557600936467257340 .
}
@prefix msg: <http://purl.org/webofneeds/message#> .
@prefix conn: <https://localhost:8443/won/resource/connection/> .
@prefix woncrypt: <http://purl.org/webofneeds/woncrypt#> .
@prefix need: <https://localhost:8443/won/resource/need/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix cert: <http://www.w3.org/ns/auth/cert#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix agr: <http://purl.org/webofneeds/agreement#> .
@prefix local: <https://localhost:8443/won/resource/> .
@prefix sig: <http://icp.it-risk.iwvi.uni-koblenz.de/ontologies/signature.owl#> .
@prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> .
@prefix s: <http://schema.org/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix won: <http://purl.org/webofneeds/model#> .
@prefix ldp: <http://www.w3.org/ns/ldp#> .
@prefix event: <https://localhost:8443/won/resource/event/> .
@prefix sioc: <http://rdfs.org/sioc/ns#> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
<https://localhost:8443/won/resource/event/ow321nn1va6clfidc4s0#envelope-l74h> {
event:ow321nn1va6clfidc4s0
msg:hasPreviousMessage event:9fhq1ef81bw0vwps12c5 .
}
<https://localhost:8443/won/resource/event/557600936467257340#envelope-xg0i> {
event:557600936467257340
msg:hasPreviousMessage event:omh6mnwfqczgjimg3sch .
}
<https://localhost:8443/won/resource/event/5669098069340991000#data> {
event:5669098069340991000
msg:hasContent <https://localhost:8443/won/resource/event/5669098069340991000#content> .
}
<https://localhost:8443/won/resource/event/557600936467257340#content> {
event:557600936467257340
agr:proposes event:5669098069340991000 .
}
<https://localhost:8443/won/resource/event/nmnetfuihnx70r0do0id#envelope-4o4g> {
event:nmnetfuihnx70r0do0id
msg:hasPreviousMessage event:5669098069340991000 .
}
<https://localhost:8443/won/resource/event/ow321nn1va6clfidc4s0#content-1o90> {
event:ow321nn1va6clfidc4s0
agr:accepts event:557600936467257340 .
}
<https://localhost:8443/won/resource/event/9fhq1ef81bw0vwps12c5#envelope-u0yx> {
event:9fhq1ef81bw0vwps12c5
msg:hasPreviousMessage event:hp6hw2wa3bbww4wo8gfo .
}
<https://localhost:8443/won/resource/event/omh6mnwfqczgjimg3sch#envelope-b7qv> {
event:omh6mnwfqczgjimg3sch
msg:hasPreviousMessage event:krcmdz8802701wpzlzl8 .
}
<https://localhost:8443/won/resource/event/krcmdz8802701wpzlzl8#envelope-qdj9> {
event:krcmdz8802701wpzlzl8
msg:hasPreviousMessage event:nmnetfuihnx70r0do0id .
}
<https://localhost:8443/won/resource/event/5669098069340991000#content> {
event:5669098069340991000
won:hasTextMessage "one" .
}
<https://localhost:8443/won/resource/event/hp6hw2wa3bbww4wo8gfo#envelope-gpzu> {
event:hp6hw2wa3bbww4wo8gfo
msg:hasCorrespondingRemoteMessage
event:557600936467257340 .
}
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(Unknown Source)
at java.util.HashMap$KeyIterator.next(Unknown Source)
at org.apache.jena.sparql.engine.main.iterator.QueryIterGraph$QueryIterGraphInner.nextIterator(QueryIterGraph.java:149)
at org.apache.jena.sparql.engine.main.iterator.QueryIterGraph$QueryIterGraphInner.hasNextBinding(QueryIterGraph.java:125)
at org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:114)
at org.apache.jena.sparql.engine.iterator.QueryIterRepeatApply.hasNextBinding(QueryIterRepeatApply.java:74)
at org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:114)
at org.apache.jena.sparql.engine.iterator.QueryIterRepeatApply.makeNextStage(QueryIterRepeatApply.java:101)
at org.apache.jena.sparql.engine.iterator.QueryIterRepeatApply.hasNextBinding(QueryIterRepeatApply.java:65)
at org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:114)
at org.apache.jena.sparql.engine.iterator.QueryIterRepeatApply.makeNextStage(QueryIterRepeatApply.java:101)
at org.apache.jena.sparql.engine.iterator.QueryIterRepeatApply.hasNextBinding(QueryIterRepeatApply.java:65)
at org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:114)
at org.apache.jena.sparql.engine.iterator.QueryIterRepeatApply.makeNextStage(QueryIterRepeatApply.java:101)
at org.apache.jena.sparql.engine.iterator.QueryIterRepeatApply.hasNextBinding(QueryIterRepeatApply.java:65)
at org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:114)
at org.apache.jena.sparql.engine.iterator.QueryIterProcessBinding.hasNextBinding(QueryIterProcessBinding.java:66)
at org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:114)
at java.util.Iterator.forEachRemaining(Unknown Source)
at org.apache.jena.atlas.data.DataBag.addAll(DataBag.java:94)
at org.apache.jena.sparql.engine.iterator.QueryIterSort$SortedBindingIterator.initializeIterator(QueryIterSort.java:87)
at org.apache.jena.atlas.iterator.IteratorDelayedInitialization.init(IteratorDelayedInitialization.java:40)
at org.apache.jena.atlas.iterator.IteratorDelayedInitialization.hasNext(IteratorDelayedInitialization.java:50)
at org.apache.jena.sparql.engine.iterator.QueryIterPlainWrapper.hasNextBinding(QueryIterPlainWrapper.java:53)
at org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:114)
at org.apache.jena.sparql.engine.iterator.QueryIterConvert.hasNextBinding(QueryIterConvert.java:58)
at org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:114)
at org.apache.jena.sparql.engine.iterator.QueryIteratorWrapper.hasNextBinding(QueryIteratorWrapper.java:39)
at org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:114)
at org.apache.jena.sparql.engine.iterator.QueryIteratorWrapper.hasNextBinding(QueryIteratorWrapper.java:39)
at org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:114)
at org.apache.jena.sparql.engine.ResultSetStream.hasNext(ResultSetStream.java:74)
at org.apache.jena.sparql.engine.ResultSetCheckCondition.hasNext(ResultSetCheckCondition.java:55)
at won.utils.agreement.AgreementFunction.applyAgreementFunction(AgreementFunction.java:51)
at won.utils.agreement.AgreementProtocolTest.test(AgreementProtocolTest.java:193)
at won.utils.agreement.AgreementProtocolTest.exposeJenaBug(AgreementProtocolTest.java:115)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:539)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:761)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:461)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:207)
PREFIX mod: <http://purl.org/webofneeds/modification#>
PREFIX agr: <http://purl.org/webofneeds/agreement#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX msg: <http://purl.org/webofneeds/message#>
PREFIX won: <http://purl.org/webofneeds/model#>
SELECT ?acc ?s ?p ?o WHERE {
GRAPH ?g1 {
?prop agr:proposes ?clause .
}
GRAPH ?g3 {
?clause msg:hasContent ?clauseContent .
}
GRAPH ?clauseContent {
?s ?p ?o .
}
# Note: for this pattern, we need the union of all graphs that contain msg:hasPreviousMessage triples,
# Jena provides the special graph name <urn:x-arq:UnionGraph> for querying the union of all the query's graphs
# THIS QUERY WILL ONLY WORK WITH JENA
GRAPH <urn:x-arq:UnionGraph> {
?prop msg:hasPreviousMessage+/msg:hasCorrespondingRemoteMessage? ?clause .
?acc msg:hasPreviousMessage+/msg:hasCorrespondingRemoteMessage ?prop .
}
GRAPH ?g2 {
?acc agr:accepts ?prop .
}
filter not exists {
GRAPH ?gc1 {
?cancelProp agr:proposesToCancel ?acc .
}
# Note: for this pattern, we need the union of all graphs that contain msg:hasPreviousMessage triples,
# Jena provides the special graph name <urn:x-arq:UnionGraph> for querying the union of all the query's graphs
# THIS QUERY WILL ONLY WORK WITH JENA
GRAPH <urn:x-arq:UnionGraph> {
?cancelProp msg:hasPreviousMessage+/msg:hasCorrespondingRemoteMessage? ?acc .
?cancelAcc msg:hasPreviousMessage+/msg:hasCorrespondingRemoteMessage ?cancelProp .
}
GRAPH ?gc2 {
?cancelAcc agr:accepts ?cancelProp .
}
GRAPH ?gc3 {
?cancelProp msg:hasContent ?gc1.
}
GRAPH ?gc4 {
?cancelAcc msg:hasContent ?gc2.
}
}
}
order by ?acc
PREFIX mod: <http://purl.org/webofneeds/modification#>
PREFIX agr: <http://purl.org/webofneeds/agreement#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX msg: <http://purl.org/webofneeds/message#>
PREFIX won: <http://purl.org/webofneeds/model#>
SELECT ?acc ?s ?p ?o WHERE {
GRAPH ?g1 {
?prop agr:proposes ?clause .
}
{
GRAPH ?clauseContent {
?s ?p ?o .
}
{
GRAPH ?g3 {
?clause msg:hasContent ?clauseContent .
}
}
}
# Note: for this pattern, we need the union of all graphs that contain msg:hasPreviousMessage triples,
# Jena provides the special graph name <urn:x-arq:UnionGraph> for querying the union of all the query's graphs
# THIS QUERY WILL ONLY WORK WITH JENA
GRAPH <urn:x-arq:UnionGraph> {
?prop msg:hasPreviousMessage+/msg:hasCorrespondingRemoteMessage? ?clause .
?acc msg:hasPreviousMessage+/msg:hasCorrespondingRemoteMessage ?prop .
}
GRAPH ?g2 {
?acc agr:accepts ?prop .
}
filter not exists {
GRAPH ?gc1 {
?cancelProp agr:proposesToCancel ?acc .
}
# Note: for this pattern, we need the union of all graphs that contain msg:hasPreviousMessage triples,
# Jena provides the special graph name <urn:x-arq:UnionGraph> for querying the union of all the query's graphs
# THIS QUERY WILL ONLY WORK WITH JENA
GRAPH <urn:x-arq:UnionGraph> {
?cancelProp msg:hasPreviousMessage+/msg:hasCorrespondingRemoteMessage? ?acc .
?cancelAcc msg:hasPreviousMessage+/msg:hasCorrespondingRemoteMessage ?cancelProp .
}
GRAPH ?gc2 {
?cancelAcc agr:accepts ?cancelProp .
}
GRAPH ?gc3 {
?cancelProp msg:hasContent ?gc1.
}
GRAPH ?gc4 {
?cancelAcc msg:hasContent ?gc2.
}
}
}
order by ?acc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment