I have written a Java Native Interface (JNI) that I would like to package into a JAR and import as a dependency into a Gradle/Java 8 project (Gradle Wrapper 4.6). The only way I am able to use my JNI classes are if I copy the native library to the Main project's /tmp directory before I initialize any module from the JAR that relies on this native library. I am using a class constructor to pass in the tmp file's absolute file path so it can be loaded in the JNI.
My questions are:
Is copying the native library from the jar and writing it to the Main application's /tmp directory best practice for a production environment? Are there other potential options using a build tool like Gradle?
Are there any potential known side effects of referencing a native library this way?
Below is how I'm copying the library in the main application:
static {
String libName = System.mapLibraryName("OnnxImp");
File tmpNativeLib = null;
try (InputStream stream = System.class.getResourceAsStream("/" + libName)) {
if (stream == null) {
throw new IllegalStateException("failed to find library " + libName);
}
tmpNativeLib = File.createTempFile(libName, null);
try (FileOutputStream tempOutputStream = new FileOutputStream(tmpNativeLib)) {
IOUtils.copy(stream, tempOutputStream);
}
} catch (Exception e) {
tmpNativeLib = null;
} finally {
onnxAPI = new OnnxAPI(tmpNativeLib.getAbsolutePath());
tmpNativeLib.delete();
}
}
Below is how I'm loading the native library in the JNI:
public class JNIClass {
public JNIClass() {
System.loadLibrary("OnnxImp");
}
public JNIClass(String tmpNativeLibPath) {
if (tmpNativeLibPath != null) {
System.load(tmpNativeLibPath);
} else {
throw new IllegalArgumentException("No library path passed into JNIClass");
}
}
...
}