Discussion on dev@

On 16/06/15 13:29, Crapo, Andrew (GE Global Research) wrote:
Andy,

Did you run as Java Application? Run as Junit test, they will all show as 
passed because Junit doesn't work for multi-threads.

Andrew

-----Original Message-----
From: Andy Seaborne [mailto:[email protected]]
Sent: Tuesday, June 16, 2015 6:56 AM
To: [email protected]
Cc: Barry Hathaway ([email protected])
Subject: Re: Threading Issue in OntDocumentManager.loadImports

Hi Andrew,

You don't need to send to users@ and dev@.

I have created JENA-965 to record this.

However, when I run the test suite, with Jena 2.13.0 or Jena 3.0.0 development 
on my machine (Ubuntu), the tests green line.

Please could someone with a Windows setup check this report.

        Andy

[1]
https://urldefense.proofpoint.com/v2/url?u=https-3A__issues.apache.org_jira_browse_JENA-2D965&d=AwIDaQ&c=IV_clAzoPDE253xZdHuilRgztyh_RiV3wUrLrDQYWSI&r=i8CxFc-ACvlO-_0l1u8bvw&m=jAjkz-0QS0ym_RvJZ8a7ICA7_0PtU1ffy4BcOhq6tD0&s=b8b6VHQqq7kEvgOJxySc1440yOPvAOT0wTcauyEV09o&e=

On 14/06/15 03:24, Crapo, Andrew (GE Global Research) wrote:
I have multiple clients accessing a common service, which runs in a
multi-threaded environment. Each client will have different scenario
data, e.g., OWL models SC1, SC2, SC3, etc. Each SCi model imports a
common hierarchy of domain models; SCi imports tbox A, which imports
tbox B, which imports tbox C. There is also a rule that inserts a new
triple into an infered model, the object value of which is specific to
the data in the input model SCi.

To validate the thread-safely of the server, I've created a test case
with one or more threads. Each thread accesses concepts in the
imported models via the thread-specific scenario model. That part of
the test code is:

                                  for (int i = 0; i < 50; i++) {

                                                  JenaBareThread
myThread = new JenaBareThread();

                                                  myThread.start();

                                  }

There are several versions of the run method of JenaBareThread. The
one that works loads one of three scenario data models, which in turn
imports the tbox models, and then queries for the inferred triple and
checks for the correct value for the given scenario. This code is of
the
form:

                  public void run() {

                                  String modelFolderDir =
"file:/C:tmp/DataModels/Shapes/OwlModels";

                                  String abox = modelFolderDir + "/Test"
+ (getInoutidx() + 1) + ".owl";

                                  String ontPolicy = modelFolderDir +
"/ont-policy.rdf";

                                  OntModel dataModel =
ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);

                                  try {


dataModel.enterCriticalSection(Lock.WRITE);


dataModel.getDocumentManager().setProcessImports(true);

                                                  dataModel.read(abox);

                                  }

                                  catch (Throwable t) {

                                                  t.printStackTrace();

                                  }

                                  finally {


dataModel.leaveCriticalSection();

                                  }

                                  String rulefn = modelFolderDir +
"/Rule.rules";

                                  List<Rule> ruleList = new
ArrayList<Rule>();

                                  try {

                                                  InputStream in =
FileManager.get().open(rulefn);

                                                  if (in != null) {

                                                                  ...
(load rule)

                                                      }


GenericRuleReasoner reasoner = new GenericRuleReasoner(ruleList);


reasoner.setDerivationLogging(true);


reasoner.setMode(GenericRuleReasoner.HYBRID);

                                                      InfModel infModel
= ModelFactory.createInfModel(reasoner, dataModel);

                                                      String askQuery =
"select ?s ?a where {?s
<https://urldefense.proofpoint.com/v2/url?u=http-3A__sadl.org_Shapes_S
hapes-23area&d=AwIDaQ&c=IV_clAzoPDE253xZdHuilRgztyh_RiV3wUrLrDQYWSI&r=
i8CxFc-ACvlO-_0l1u8bvw&m=jAjkz-0QS0ym_RvJZ8a7ICA7_0PtU1ffy4BcOhq6tD0&s
=dXUMM-0ffTeodArINKg6KB45gF4vodJjN3xeHSb3NEA&e= > ?a}";

                                                      QueryExecution
qexec = QueryExecutionFactory.create(QueryFactory.create(askQuery,
Syntax.syntaxARQ), infModel);

                                                      ResultSet results
= qexec.execSelect();

                                                      ... (test
results)

                                                  }

                                  }

                                  catch (RulesetNotFoundException e) {

                                                  e.printStackTrace();

                                  }

                                  catch (HttpException e) {

                                                  e.printStackTrace();

                                  }

In this test the scenario models are pre-existing and the
multi-threaded test passes for all threads regardless of the number of threads.
However, I really need to construct each scenario model with data
coming from the client. This I am unable to do without encountering
various errors which apprear to be due to threading issues.

There are 3 other versions of the test, each trying a different way of
creating a scenario model with data not already in an OWL file. For
each, if I run 1 thread the test passes. If I set breakpoints and run
multiple threads, the test passes for each thread. Otherwise I get a
errors. Several of the problems appear to occur when a call is made to
find a concept in one of the imported models. For example, one version
has this in the run method:

                                  long timestamp =
System.currentTimeMillis();

                                  String tsStr = "" + timestamp;

                                  OntModel dataModel =
ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);

                                  try {


dataModel.enterCriticalSection(Lock.WRITE);


dataModel.setDynamicImports(true);

                                                  ReadFailureHandler
rfHandler = new SadlReadFailureHandler(logger);


dataModel.getDocumentManager().setReadFailureHandler(rfHandler );


dataModel.getDocumentManager().setMetadataSearchPath(ontPolicy, true);


dataModel.getDocumentManager().setProcessImports(true);


dataModel.createOntology(aboxNS);

                                                  Ontology ont =
dataModel.getOntology(aboxNS);

                                                  Resource imp =
dataModel.createResource(ruleNS);

                                                  ont.addImport(imp);

                                                  OntClass cls =
dataModel.getOntClass(rectNS + "#Rectangle");

                                                  Individual inst =
dataModel.createIndividual(aboxNS + "#MyRect", cls);

                                                  assertNotNull(inst);

                                                  OntProperty height =
dataModel.getOntProperty(rectNS + "#height");


assertNotNull(height);

                                                  OntProperty width =
dataModel.getOntProperty(rectNS + "#width");

                                                  assertNotNull(width);

                                                  String last3 =
tsStr.substring(tsStr.length() - 3);

                                                  float w =
Float.parseFloat(last3);

                                                  float h = w + 10;

                                                  area = h * w;


inst.addProperty(height, dataModel.createTypedLiteral(w));


inst.addProperty(width,  dataModel.createTypedLiteral(h));

On a few threads, at least one of the calls to dataModel.getOntClass
or dataModel.getOntProperty returns null. This is because
MultiUnion.graphBaseContains(Triple t) returns false.

The stack trace looks like this:

                  MultiUnion.graphBaseContains(Triple) line: 132

                  MultiUnion(GraphBase).contains(Triple) line: 321

                  MultiUnion(GraphBase).contains(Node, Node, Node)
line: 338

                  OntModelImpl.findByURIAs(String, Class<T>) line: 2873

                  OntModelImpl.getOntClass(String) line: 908

                  JenaBareThread3.run() line: 76

Further examination shows that the m_subGraphs ArrayList contains an
incomplete set of imports, sometimes only 2, sometimes 3 and sometimes
the 4 that it should contain. This appears to be the case because the
transitive closure of imports performed by
OntDocumentManager.loadImports does not always load all of the
indirect imports.

I will try attaching a ZIP containing an export of the Eclipse project
containing all tests and the models required. It can be imported into
Eclipse and only the one line setting the location of the
"modelFolderDir" will need adjusting to the path to which the project
is imported. Since my recollection is that attachments here will not
work, I've also shared this ZIP file publicly on Google Drive at
https://urldefense.proofpoint.com/v2/url?u=https-3A__drive.google.com_file_d_0B7lXpNc8yGmTWFZZZzRHOWdtZTQ_view-3Fusp-3Dsharing&d=AwIDaQ&c=IV_clAzoPDE253xZdHuilRgztyh_RiV3wUrLrDQYWSI&r=i8CxFc-ACvlO-_0l1u8bvw&m=jAjkz-0QS0ym_RvJZ8a7ICA7_0PtU1ffy4BcOhq6tD0&s=Njb5_TowaUVWyAFyicdibguyZIuMRjI3qBFpqeXO_5w&e=
 .

Any insight into why this doesn’t work/how to create data models in a
thread-safe manner would be greatly appreciated!

**

*Andrew W Crapo*

Information Scientist

GE Global Research

T +1 518 387-5729

[email protected] <mailto:[email protected]>

One Research Circle

Niskayuna, NY 12302 USA

GE imagination at work



Reply via email to