Search code examples
scalasparqlrdf4j

Scala RDF4J application won't terminate


I have been writing a fair amount of Scala + RDF4J over the past several months. So far so good.

I just wrote this today, and the application won't terminate. It prints out the requested three triples and the word "done" but doesn't return to a sbt command prompt (or, in Eclipse, the stop button stays red and hovering over the run button brings up a "already running message")

What the heck am I doing wrong? I have run it against several different endpoints, including a RDF4J server, Virtuoso, and Blazegraph.

My source

import org.eclipse.rdf4j.query.QueryLanguage
import org.eclipse.rdf4j.repository.sparql.SPARQLRepository

object sharedMain {
  def main(args: Array[String]): Unit = {

    val sparqlEndpoint = "https://dbpedia.org/sparql"
    val SparqlRepo = new SPARQLRepository(sparqlEndpoint)
    SparqlRepo.initialize()

    var con = SparqlRepo.getConnection()

    var queryString = "SELECT ?x ?y WHERE { ?x ?p ?y } limit 3 "
    val tupleQuery = con.prepareTupleQuery(QueryLanguage.SPARQL, queryString)
    var result = tupleQuery.evaluate()

    while (result.hasNext()) { // iterate over the result
      val bindingSet = result.next()
      val valueOfX = bindingSet.getValue("x")
      val valueOfY = bindingSet.getValue("y")
      val toPrint = valueOfX + " -> " + valueOfY
      println(toPrint)
    }

    result.close
    con.close

    println("done")
  }
}

My build.sbt

name := "tripleStoreTesting"
version := "0.1"
scalaVersion := "2.12.0"
resolvers += Classpaths.typesafeReleases
libraryDependencies ++= Seq(
    "ch.qos.logback" % "logback-classic" % "1.1.5" % "runtime",
    "org.scalactic" %% "scalactic" % "3.0.1",
    "org.scalatest" %% "scalatest" % "3.0.1" % "test",
    "org.eclipse.rdf4j" % "rdf4j-runtime" % "2.2.2",
    "commons-logging" % "commons-logging" % "1.2"
)
mainClass := Some("sharedMain")

Solution

  • As AKSW suggested, I haven't closed or shut down everything I have opened, started, initialized, etc.

    // Scala code snippet, 
    // starting with my program's last interaction with the triplestore
    
    while (result.hasNext) { // iterate over the result
      val bindingSet = result.next
      val valueOfX = bindingSet.getValue("x")
      val valueOfY = bindingSet.getValue("y")
      val toPrint = valueOfX + " -> " + valueOfY
      println(toPrint)
    }
    
    result.close
    con.close
    
    // ADD THIS for proper application termination
    SparqlRepo.shutDown
    

    In addition to the JavaDocs AKSW posted, the RDF4J programming tutorial does a pretty good job of emphasizing the many things that need to be closed properly.

    • connections
    • result iterators
    • statement iterators
    • input streams
    • naturally, files

    It just doesn't specifically mention shutting down SPARQLRepository instances.