Question

I am using JENA to create a triple store (TDB functionality) with the following code:

public void createTDBFromOWL() {
    Dataset dataset = TDBFactory.createDataset(newTripleStoreLocation);

    dataset.begin(ReadWrite.WRITE);

    try {
        //getting the model inside the transaction
        Model model = dataset.getDefaultModel();
        FileManager fileManager=FileManager.get();
        Model holder=fileManager.readModel(model, newOWLFileLocation);

        //committing dataset
        dataset.commit();

        model.close();
        holder.close();
    } finally {
        dataset.end();
        dataset.close();
    }

}

After I create the triple store, the files created are locked by my application server (Glassfish), and I can't delete them until I manually stop Glassfish and it releases its lock. As shown in the above code, I think I am closing everything, so I don't get why a lock is maintained on the files.

Was it helpful?

Solution

When you call Dataset#close(), the implementation delegates that call to an underlying DatasetGraphBase#close(), which then ultimately delegates to DatasetGraphTDB#_close().

This results in calls to TripleTable#close() and QuadTable#close(). Both of these call (several) NodeTupleTable#close(). Continuing with the indirection, this calls NodeTable#close() and TupleTable#close(). The former is an interface, so we'd need to make a proper guess as to which class is run in your implementation. The latter iterates through a collection of TupleIndex objects and calls close() on each of them. TupleIndex is, also, an interface.

There is only one meaningful heirarchy of descendents from TupleIndex that results in something which can lock a file, which leads us to TupleIndexRecord#close(). We can then follow a particular implementation of RangeIndex called BPlusTree all the way down until we see actual ownership of the MappedByteBuffer

Ultimately, while reading the implementation of BlockAccessMapped#close(), it seems like the entire heirarchy is closing things properly, down to the final classes, but that this longstanding bug may be the culprit. From the documentation:

once a file has been mapped a number of operations on that file will fail until the mapping has been released (e.g. delete, truncating to a size less than the mapped area). However the programmer can't control accurately the time at which the unmapping takes place --- typically it depends on the processing of finalization or a PhantomReference queue.

So there you have it. Despite Jena's best efforts, one cannot yet control when that file will be unmapped in Java. This ends up being the tradeoff for memory-mapped file IO in java.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top