Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deleteting a temp file after loading into JVM

Is it ok to delete a library file right after we load it using the system.loadLibrary() function...? Here is the scenario...

We are using JNI to use the DomainSocket utility which is written in C language to call from a Java app. We are packing the .SO files in the same jar and using a utility to create a temp file on the file system and load the .SO using the loadLibrary function. We are using the File.createTempFile() which create a unique temp file. We are using the deteleOnExit()to delete the temp file on JVM shutdown.

On a stand alone application on JVM, this works fine. But we have an issue when deployed to web container like Tomcat as we can have multiple applications running on the same JVM. Firstly a temp file is created for each App deployed. The real problem is that when the App is stopped and started or re-deployed, the temp file is not deleted, but a new one created. All the temp files are deleted when the JVM shuts down (Tomcat restarted).

We experimented with a solution to delete the temp file after the loadLibrary(). This seems to works fine. A new temp file is created on restart and deleted right after loading.

Wanted to check if anybody has some pointers/suggestions?

We do not want to use the common/lib mechanism to load the .SO files only once per container as we want to make these .SO files part of the application.

like image 650
user2089210 Avatar asked Mar 27 '16 21:03

user2089210


1 Answers

Is it ok to delete a library file right after we load it using the system.loadLibrary() function...?

Nope. The OS is free to "unload" the library at any time and might have to re-load the binary from the disk. If you delete the file (and it's not actually held-open by the process), then you'll get some very weird behavior .. probably something like a "BUS ERROR" or other barely-explainable condition.

Even if the library is not dropped from memory and re-loaded from the disk, various OSs have flags for "lazy loading" and other things that can get you into a race-condition situation where you might delete the on-disk library artifact before all the code was actually loaded from it.

We are using the File.createTempFile() which create a unique temp file. We are using the deleteOnExit() to delete the temp file on JVM shutdown.

This seems like a reasonable approach, except for the problems you are encountering. Instead of using File.createTempFile, why not use a predictable filename in a predictable place (such as /tmp/libgoodstuff.so)? If you do that, then you'll only have to create (and schedule the deletion of) a single file (per library you want to load).

[I] wanted to check if anybody has some pointers/suggestions?

Placing the .so file in the application is going to be tough to manage unless you really know your target environments very well. For example, you'll need to make sure you have your target architecture and OS correct, etc.

The bottom line is that native libraries as a part of a distributable application are a pain in the neck with Java and should be avoided unless there are no other options.

like image 93
Christopher Schultz Avatar answered Oct 13 '22 06:10

Christopher Schultz