Hi Andy, Thanks for your reply. I tried your 2nd Option. The StoreConnection.release(location) option didn't seem to work. I'm assuming the location should point to the main TopLevel Directory
/etc/fuseki/databases/201906031724/ ├── Data-0001 │ ├── GOSP.bpt │ ├── GOSP.dat | | ... │ └── tdb.lock └── tdb.lock I gave "/etc/fuseki/databases/201906031724" as location input private boolean postProcessingWebServer(String path) { Location location = Location.create(path); String lockFilename = location.getPath(Names.TDB_LOCK_FILE); LOGGER.info("location {} is presence in StoreConnection.cache is {}", lockFilename, StoreConnection.isSetup(location)); StoreConnection.release(location); return ExecUtil.restartJetty(); } INFO location /etc/fuseki/databases/201906031724/tdb.lock is presence in StoreConnection.cache is false This option failed with the same original error. The storeConnection has a cache, and this location was not in that cache(). ============= So next I tried the following option private boolean postProcessingWebServer(String path) { Location location = Location.create(path); String lockFilename = location.getPath(Names.TDB_LOCK_FILE); LOGGER.info("location of the lock file is {}", lockFilename); StoreConnection storeConnection = StoreConnection.connectCreate(location); storeConnection.getLock().unlock(); return ExecUtil.restartJetty(); } This time I got the following error org.apache.jena.dboe.base.file.AlreadyLocked: Failed to get a lock: file='/etc/fuseki/databases/201906031727/tdb.lock': Lock already held at org.apache.jena.dboe.base.file.ProcessFileLock.lockOperation(ProcessFileLock.java:187) at org.apache.jena.dboe.base.file.ProcessFileLock.lockEx(ProcessFileLock.java:125) at org.apache.jena.tdb2.sys.StoreConnection.make(StoreConnection.java:87) at org.apache.jena.tdb2.sys.StoreConnection.connectCreate(StoreConnection.java:61) at org.apache.jena.tdb2.sys.StoreConnection.connectCreate(StoreConnection.java:52) ======== Then I tried to use the ProcessFileLock directly private boolean postProcessingWebServer(String path) { Location location = Location.create(path); String lockFilename = location.getPath(Names.TDB_LOCK_FILE); ProcessFileLock fileLock = ProcessFileLock.create(lockFilename); LOGGER.info("Lock exists for {} is {}", lockFilename, fileLock.isLockedHere()); fileLock.unlock(); return ExecUtil.restartJetty(); } INFO Lock exists for /etc/fuseki/databases/201906031755/tdb.lock is true Caused by: org.apache.jena.dboe.DBOpEnvException: Failed to get a lock: file='/etc/fuseki/databases/201906031755/Data-0001/tdb.lock': held by process 8211 at org.apache.jena.dboe.base.file.ProcessFileLock.lockOperation(ProcessFileLock.java:199) at org.apache.jena.dboe.base.file.ProcessFileLock.lockEx(ProcessFileLock.java:125) at org.apache.jena.tdb2.sys.StoreConnection.make(StoreConnection.java:87) at org.apache.jena.tdb2.sys.StoreConnection.connectCreate(StoreConnection.java:61) at org.apache.jena.tdb2.sys.DatabaseOps.createSwitchable(DatabaseOps.java:97) at org.apache.jena.tdb2.sys.DatabaseOps.create(DatabaseOps.java:78) at org.apache.jena.tdb2.sys.DatabaseConnection.buildForCache(DatabaseConnection.java:90) at org.apache.jena.tdb2.sys.DatabaseConnection.lambda$make$0(DatabaseConnection.java:76) at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660) at org.apache.jena.tdb2.sys.DatabaseConnection.make(DatabaseConnection.java:76) at org.apache.jena.tdb2.sys.DatabaseConnection.connectCreate(DatabaseConnection.java:61) at org.apache.jena.tdb2.sys.DatabaseConnection.connectCreate(DatabaseConnection.java:52) This time the error was for the lock file which is inside the Data-0001 folder instead. ===== When I tried using the unlock on both the lock file explicitly, it worked. I also tried the TDBInternal.expel(dataset) and it worked private boolean postProcessingWebServer(String path) { Location location = Location.create(path); DatabaseConnection databaseConnection = DatabaseConnection.connectCreate(location); TDBInternal.expel(databaseConnection.getDatasetGraph()); return ExecUtil.restartJetty(); } I'm going ahead with the TDBInternal.expel option for now. Regards Amit On Sat, Jun 1, 2019 at 5:59 AM Andy Seaborne <a...@apache.org> wrote: > Hi Amit, > > You are correct - when used in a JVM, the dataset remains manged by the > JVM after loading. This is intentional - the app may want to use the > dataset some more in Java code. > > You can: > 1/ Fork the process as a separate OS process using java.util.ProcessBuilder > > 2/ Force it out of the running JVM with > TDBInternal.expel(dataset) > or > StoreConenction.release(location) > > 3/ Work with the dataset in Fuseki - you can POST data to it > > 4/ Not use a war file but use Fuseki main, and run your program and > Fuseki in the same JVM. > > Symbolic links make no difference - they are only involved in file > system path naming. Once opened, the OS pathname isn't involved. > > Andy > > On 31/05/2019 21:23, Amit Kumar wrote: > > Hi, > > I'm having issue an issue with using Fuseki as a war file inside jetty. > We > > have a java application which looks for new data and loads it onto > fuseki. > > When it is doing it for the first time, it has to create a new index, so > we > > call the tdb2.tdbloader class directly with appropriate parameters. Here > is > > the relevant code snippet > > > > import tdb2.tdbloader; > > > > ... > > > > public static List<String> TDBLoaderParams = Arrays.asList("-q", > >> "--loader", "parallel", "--loc"); > >> ... > >> List<String> tdbParams = new ArrayList<>(TDBLoaderParams); > >> tdbParams.add(dstPath); > >> tdbParams.addAll(srcPaths); > >> try { > >> ... > >> tdbloader.main(tdbParams.toArray(new String[tdbParams.size()])); > >> } > >> ... > >> ... > >> > > > > > > This works as expected and create a new index at the desired location. > Now, > > the problem is the same java process has to apply other feeds onto the > same > > graph, so we move the softlink pointing to the fuseki database and > execute > > a jetty restart command by calling a shell action using Java > ProcessBuilder > > process. > > The jetty though fails to restart with the following error: > > > >> > >> org.apache.jena.assembler.exceptions.AssemblerException: caught: Failed > to > >> get a lock: file='/home/amit/fuseki/databases/201905302214/tdb.lock': > >> held by process 35918 at > >> > org.apache.jena.assembler.assemblers.AssemblerGroup$PlainAssemblerGroup.openBySpecificType(AssemblerGroup.java:165) > >> at > >> > org.apache.jena.assembler.assemblers.AssemblerGroup$PlainAssemblerGroup.open(AssemblerGroup.java:144) > >> at > >> > org.apache.jena.assembler.assemblers.AssemblerGroup$ExpandingAssemblerGroup.open(AssemblerGroup.java:93) > >> at > >> > org.apache.jena.assembler.assemblers.AssemblerBase.open(AssemblerBase.java:39) > >> at > >> > org.apache.jena.assembler.assemblers.AssemblerBase.open(AssemblerBase.java:35) > >> at > >> > org.apache.jena.fuseki.build.FusekiConfig.getDataset(FusekiConfig.java:353) > >> at > >> > org.apache.jena.fuseki.build.FusekiConfig.buildDataService(FusekiConfig.java:303) > >> at > >> > org.apache.jena.fuseki.build.FusekiConfig.buildDataAccessPoint(FusekiConfig.java:292) > >> at > >> > org.apache.jena.fuseki.build.FusekiConfig.readConfiguration(FusekiConfig.java:275) > >> at > >> > org.apache.jena.fuseki.build.FusekiConfig.readConfigurationDirectory(FusekiConfig.java:254) > >> ... ... Caused by: org.apache.jena.dboe.DBOpEnvException: Failed to get > a > >> lock: file='/home/amit/fuseki/databases/201905302214/tdb.lock': held by > >> process 35918 at > >> > org.apache.jena.dboe.base.file.ProcessFileLock.lockOperation(ProcessFileLock.java:199) > >> at > >> > org.apache.jena.dboe.base.file.ProcessFileLock.lockEx(ProcessFileLock.java:125) > >> at > >> > org.apache.jena.tdb2.sys.DatabaseConnection.buildForCache(DatabaseConnection.java:88) > >> at > >> > org.apache.jena.tdb2.sys.DatabaseConnection.lambda$make$0(DatabaseConnection.java:76) > >> at > >> > java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660) > >> > > > > So the Jetty Server fails to restart while the jvm that created the index > > is still active, even though it has completed the index building part. It > > restarts fine once the loader JVM dies. It looks like the parallel > loader > > class is not releasing the lock() properly. FYI, I'm using 3.11 Jena > > > > From apache jena github > > > https://github.com/apache/jena/blob/66d14eda44dd0f37a9df31ed27c55c26600ff5f8/jena-db/jena-dboe-base/src/main/java/org/apache/jena/dboe/base/file/ProcessFileLock.java#L184-L218 > > > > > > > > Regards > > Amit Kumar > > >