Skip to : [Content] [Navigation]
 

How do I use Pellet with Jena concurrently?

We document here the thread-safe use of Pellet in Jena applications, including operations and configuration options that may be problematic. We assume that the KB is represented and manipulated using a Jena InfModel associated with a PelletReasoner. (Examples demonstrating this use model are included in the Pellet release distribution: see examples/org/mindswap/pellet/examples/JenaReasoner.java.)

Concurrency in Jena, independent of Pellet, is discussed in the Jena documentation. This includes discussion of locking mechanisms to control concurrent access to a single Model object.

Basic Approach

Pellet cannot be used via the Jena interface in a multi-threaded fashion without explicit calls to prepare the knowledge base following any model modification. Without explicit calls, the knowledge base will perform processing operations as needed, which may lead to concurrent modification of internal data structures and incorrect query results.

To insure thread safety, modifications should be followed by a call to classify method on the PelletInfGraph underlying the InfModel. The following code example illustrates this pattern.

Model model = ModelFactory.createOntologyModel( PelletReasonerFactory.THE_SPEC, model );
model.read( "http://example.org/ontology" );

/* ... any additional model modification ... */

((PelletInfGraph) model.getGraph()).classify();
model.query( ... );

Note that because the classify method performs many operations, including loading the knowledge base, classification, and individual realization, it may be a costly operation. classify does not need to be called after each modification, but it must be called between any modification and query operations.

Constraints

In addition to forcing processing between modification and query operations, some additional use constraints should be enforced.

Incremental Reasoning

Incremental reasoning, as implemented in Pellet-1.5.1, is not-thread safe. It is disabled by default, and should not be enabled if Pellet is used concurrently by multiple threads.

Complex Concept Descriptions

Concurrent query answering is possible, in part, because the reasoner is able to classify the concept hierarchy, as a batch operation, prior to any query requests. Queries that involve unnamed concepts require classification of the concept at query time, causing modifications to internal data structures that are not thread-safe. The following SPARQL query includes a concept that makes the query unsafe

SELECT ?C WHERE {?C rdfs:subClassOf [
        rdf:type owl:Restriction ;
        owl:onProperty ub:takesCourse ;
        owl:minCardinality 2
            ]
}

To avoid problems during concurrent querying, queries should only use named concepts. If necessary, queries using unnamed concepts should be executed without any concurrent model access.

Queries with Posited Models

Jena provides a method listStatements(Resource,Property,RDFNode,Model) in the InfModel interface that permits queries to use vocabulary terms that exist in a posited Model, but not in the InfModel being queried. This method causes temporary modifications to internal data structures and cannot safely be used with concurrent query operations. If necessary, the method should be executed without any concurrent model access.