I have a dynamic library libOne.dylib written in Rust and I'd like to call it from Java over JNI. I have the sources for the Rust part but can't change them so I've written a thin C wrapper as the JNI counterpart. I can compile and link my wrapper as libTwo.dylib and load it into the JVM.
Unfortunately, the next thing the JVM is doing is loading libOne by looking into the folder where this library was placed during the time it was built so effectively I can't even start my Java application in any other environment without creating the same path where the Rust project is located on my machine and placing the libOne inside it.
Is it possible to change this behavior so that the library looked for in the same folder as the wrapper? I would prefer to completely embed the libOne into libTwo, but I'm not sure if it is possible/feasible. Ideally, I'd like to package the resulting library(ies) directly into the fat jar.
This is how I'm creating the wrapper library.
LIBS="$(pwd)/lib"
gcc \
-dynamiclib \
-shared \
-I$JAVA_HOME/include \
-I$JAVA_HOME/include/darwin \
-I$JAVA_HOME/include/linux \
*.c \
-o $LIBS/libTwo.dylib \
-L$LIBS \
-lOne \
-Wl,-rpath,.
It is placed directly in the Java project's lib folder but still looks up in the path it was initially built.
The exception looks like following:
java.lang.UnsatisfiedLinkError: /Users/user/LIB-TWO-PROJECT/lib/lobTwo.dylib:
dlopen(/Users/user/LIB-TWO-PROJECT/lib/libTwo.dylib, 1):
Library not loaded: /Users/user/LIB-ONE-PROJECT/target/release/deps/libOne.dylib
Referenced from: /Users/user/LIB-TWO-PROJECT/lib/lobTwo.dylib
Reason: image not found
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1824)
at java.lang.Runtime.load0(Runtime.java:809)
at java.lang.System.load(System.java:1086)
Please note that the path for libOne is the LIB-ONE-PROJECT release folder (target/release/deps) and not the LIB-TWO-PROJECT/lib where both libs are placed.