3

I am trying to load a native library into the system by copying a .DLL in a jar file to a temporary file, and then loading that file:

try (InputStream in = getResourceStream("/lib/Foo.dll")) {
  File file = createTemporaryFileFromStream(in);
  System.load(file.getAbsolutePath());
  if (!file.delete()) {
    System.err.println("Failed to delete temporary file " + file.getAbsolutePath());
  }
}

But the file.delete() call fails, and I'm left with a temporary file.

If I remove the System.load(...) call then the temporary file can be deleted, so it seems that System.load(...) keeps a file resource open which prevents the file delete from working (this is on a Windows 7 64-bit machine).

I also added a file.deleteOnExit() call, but the temporary file still remains after the JVM shuts down.

I also added a custom shutdown hook, just in case:

Runtime.getRuntime().addShutdownHook(new Thread() {
  public void run() {
    if (file.exists()) {
      if (!file.delete()) {
        System.err.println("Shutdown failed to delete file " + file.getAbsolutePath());
      }
    }
  }
});

Again the temporary file was not deleted.

I'd really like to load a .DLL from a jar file instead of modifying the java.library.path system property and pointing to the absolute location of the .DLL, and although the code above does in fact load the .DLL from a jar file resource, it leaves behind a temporary file, which is not acceptable.

Is there a way to do this using temporary files that can be removed after the library has been loaded?

John Q Citizen
  • 197
  • 3
  • 11
  • 1
    Possible duplicate of [How to unload library (DLL) from java JVM](http://stackoverflow.com/questions/453359/how-to-unload-library-dll-from-java-jvm) – Andreas Oct 20 '15 at 01:09
  • Thanks for the info on unloading DLLs. I will look into it. Although that solution depends on calling _System.gc()_ which is not guaranteed to actually do any memory cleanups when called (IIRC), so file descriptors held in _FileOutputStream_ may not always be released . – John Q Citizen Oct 20 '15 at 04:56
  • I added a custom class loader as suggested, and ran the garbage collector after nulling the class loader and loaded class. Without a _System.load()_ call I can see the finalizers get invoked on those objects. When there is a _System.load()_ call, however, the finalizers do not get invoked during garbage collection. Grrr. – John Q Citizen Oct 21 '15 at 01:03
  • Well, maybe the DLL code is not correctly releasing object references. – Andreas Oct 21 '15 at 03:32
  • I will try a different .DLL and see what happens ... – John Q Citizen Oct 21 '15 at 23:25

0 Answers0