ksclarke ksclarke - 2 months ago 10
C++ Question

Load statically compiled library in Java

I'm having trouble loading a statically compiled library from Java using System.loadLibrary("") but I can load it as a dynamically compiled library (when I build it that way) just fine. I'm using JDK 8 and my understanding is it can load static libraries via System.loadLibrary("") if you provide a JNI_OnLoad_L in the *.cpp and *.h files.

My kdu_jni.h has:

extern "C"
JNIEXPORT jint JNICALL JNI_OnLoad_kdu_1jni(JavaVM *, void *);


My kdu_jni.cpp has:

JNIEXPORT jint JNICALL JNI_OnLoad_kdu_1jni(JavaVM *vm, void *reserved)
{
return JNI_VERSION_1_8;
}


I have the libkdu_jni.a file in my java.library.path directory when I try to run with the compiled version. It's working fine with a libkdu_jni.so file in that same directory when I try to load it dynamically. When trying with the static file (libkdu_jni.a), I get:

Exception in thread "main" java.lang.UnsatisfiedLinkError: no kdu_jni in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1122)


I've taken out the .so file before trying to load the .a file.

I'm not sure what I'm doing wrong. I don't think it's even seeing the libkdu_jni.a file's JNI_OnLoad_kdu_1jni() because I put an exception in there and I don't see that getting thrown. I've tried several iterations on that name: JNI_OnLoad_kdu_jni(), JNI_OnLoad_kdu_1jni(), JNI_OnLoad(), etc.

Any ideas?

EJP EJP
Answer

my understanding is it can load static libraries via System.loadLibrary("") if you provide a JNI_OnLoad_L in the *.cpp and *.h files.

Your understanding is incorrect. You can't load a .a file dynamically. It isn't executable in any way shape or form:

  • infra-library references are not resolved
  • references outside the library are not resolved either: for example, to the C library.

The link step is essential, and the JVM doesn't do it for you. What you have read applies to libraries statically linked into the JVM.

Comments