You are here: Home » Data » Documents » Development » RDF files » Java developers only » Querying/Reasoning with Jena and SPARQL

Querying/Reasoning with Jena and SPARQL

Here is a short overview and comparison of RDF querying with SPARQL and Jena which is presented as follows: 1. SPARQL; 2. SPARQL from inside Jena; 3. Explicit and implicit relations when querying with Jena 4.Querying remote SPARQL endpoitns


The Simple Protocol and RDF Query Language (SPARQL) is a SQL-like language for querying RDF data. For expressing RDF graphs in the matching part of the query.  SPARQL is emerging as the de-facto RDF query language, and is a W3C Recommendation.

For our purposes SPARQL queries could be executed either directly through the SPARQL query panel in Protege or from inside a JAVA application using the specialised Jena library methods.  Both approaches are able to handle queries concerning explicit object and property relations but Jena libraries have the advantage of using a reasoner. Thus queries executed using Jena library methods can return results taking in account also the transitive and inferred relations.

Here is an example for querying the ontology 

PREFIX ot: <> 
PREFIX rdfs: <> 
SELECT  ?uri 
    ?uri rdfs:subClassOf <ot:Feature>. 


Each SPARQL request starts with PREFIXes which denote the namespaces used in the query afterwards.The first lines defines namespace prefix, the last two lines use the prefix to express a RDF graph to be matched. Identifiers beginning with question mark ? identify variables. In this query, we are looking for resource ?uri participating in triples with predicates rdfs:subClassOf and want the subjects of these triples. Detailed SPARQL syntax description can be found here.

Since SPARQL is not aware of the rdfs semantics (hence SPARQL is not aware of owl's semantics). SPARQL doesn't understand the subclass assertions (which are processed as any assertion) and it doesn't understand that rdfs:subClassOf is transitive. Executed from inside Protege this example would return as result only the direct descendats of the class ot:Feature and nothing else. If we want to obtain a full list of subclasses of the ot:Feature class we need to do it using Jena Lib methods.

2. SPARQL from inside Jena

Jena supports several different ontology model specifications.  OntModelSpec.OWL_MEM_MICRO_RULE_INF  contains Transitive Reasoner which can be used to infer rdfs:subClassOf and rdfs:subPropertyOf. In contrast the model OWL_MEM does not contain such. Thus The same query we've shown above would return the same result as in Protege if we run in from inside Jena using the simpler model and it will return the entire subtree of subclass if we run it with the model using inference. Executing the following example you will be able to see the difference in the resultset using the two different models.

public static void main (String args[]) {
        String SOURCE = "";
        String NS = SOURCE + "#";
       //create a model using reasoner
        OntModel model1 = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM_MICRO_RULE_INF);
       //create a model which doesn't use a reasoner
        OntModel model2 = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM);
                // read the RDF/XML file SOURCE, "RDF/XML" ); SOURCE, "RDF/XML" );         //prints out the RDF/XML structure         qe.close();         System.out.println(" ");             // Create a new query     String queryString =              "PREFIX rdfs: <> "+         "PREFIX rdf: <>  "+         "select ?uri "+         "where { "+          "?uri rdfs:subClassOf <>  "+         "} \n ";     Query query = QueryFactory.create(queryString);     System.out.println("----------------------");     System.out.println("Query Result Sheet");     System.out.println("----------------------");     System.out.println("Direct&Indirect Descendants (model1)");     System.out.println("-------------------");        // Execute the query and obtain results     QueryExecution qe = QueryExecutionFactory.create(query, model1);     com.hp.hpl.jena.query.ResultSet results =  qe.execSelect();     // Output query results        ResultSetFormatter.out(System.out, results, query);     qe.close();         System.out.println("----------------------");     System.out.println("Only Direct Descendants");     System.out.println("----------------------");         // Execute the query and obtain results     qe = QueryExecutionFactory.create(query, model2);     results =  qe.execSelect();     // Output query results        ResultSetFormatter.out(System.out, results, query);     qe.close(); }

Prints out the following result:

Query Result Sheet
Direct&Indirect Descendants (model 1)
| uri                                               |
| <>   |
| <>   |
| <>    |
| <>          |
| <>           |
| <>       |
| <>     |
| <>        |
| <>            |
| <> |
| <>            |
| <>           |

Only Direct Descendants (model 2)
| uri                                             |
| <> |
| <> |
| <>  |

3. Explicit and implicit relations when querying with Jena predefined methods only

From inside Jena one could query the RDF knowledge base also without using SPARQL but by predefined predicates. Here if one wants to query for transitive and inferred relations he must use again a model with a reasoner. Most of the methods for selection have a boolean argument specifying whether only direct or indirect relations must be analysed. The same example shown above executed using only Jena methods would look as follows.

public static void main (String args[]) {
         // create the base model using reasoner
        String SOURCE = "";
        String NS = SOURCE + "#";
        OntModel base = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM_MICRO_RULE_INF); SOURCE, "RDF/XML" );

        System.out.println( "These are all direct&indirect subClasses of Feature");
        OntClass event = base.getOntClass( NS + "Feature" );

//listSubClasses(bool direct) - the false stands for direct and indirect descendants         for (Iterator<OntClass> i = event.listSubClasses(false); i.hasNext(); ) {            OntClass c = (OntClass);           System.out.println( c.getURI() );         }                 System.out.println( "-------------------------" );         System.out.println( "These are only the direct subClasses of Feature");         System.out.println( "-------------------------" );         OntClass event = base.getOntClass( NS + "Feature" ); //listSubClasses(bool direct) -  true stands for direct descendants only         for (Iterator<OntClass> i = event.listSubClasses(true); i.hasNext(); ) {            OntClass c = (OntClass);           System.out.println( c.getURI() );         }     }


4. Querying remote SPARQL services

Jena provides convenience methods for querying and processing results of a remote SPARQL endpoint, via its QueryExecutionFactory class:

import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.ResultSetFormatter;

        String ontology_service = "";
	String endpoint = "otee:Endpoints";
	String endpointsSparql = 
	"PREFIX ot:<>\n"+
	"	PREFIX ota:<>\n"+
	"	PREFIX owl:<>\n"+
	"	PREFIX dc:<>\n"+
	"	PREFIX rdfs: <>\n"+
	"	PREFIX rdf:<>\n"+
	"	PREFIX otee:<>\n"+
	"		select ?url ?title\n"+
	"		where {\n"+
	"		?url rdfs:subClassOf %s.\n"+
	"		?url dc:title ?title.\n"+
	"		}\n";

 QueryExecution x = QueryExecutionFactory.sparqlService(ontology_service, String.format(endpointsSparql,endpoint));
 ResultSet results = x.execSelect();
 ResultSetFormatter.out(System.out, results);


| url                                                                    | title                                                                       |
| <>      | "Physicochemical effects "^^<>       |
| <>              | "Toxicokinetics "^^<>                |
| <>             | "Ecotoxic effects"^^<>               |
| <>          | "Human health effects"^^<>           |
| <> | "Environmental fate parameters "^^<> |

Additional information may be found at:

Document Actions