JNI: UnsatisfiedLinkError: Can't find dependent libraries
Solution 1
It looks like my problem was the combination of a 64-bit system and java installation and 32-bit C compiler.
By default, the Visual C++ cl
compiler generates 32-bit applications, and this caused an error when loaded by 64-bit java. I compiled my application with the Windows SDK 7.1 64-bit compiler, and it ran with no error, as well as removing the warnings in Dependency Walker.
Solution 2
I tried getting JNI to work for a final project for school and ended up looking for alternatives after a month of head-banging. Try Java Native Access instead. It lets you call any C function from any shared library on Windows (.dll) and Linux (.so), and it even has convenience methods for some Win32 functions. Compile your native code into a shared library, then use JNA to dynamically link to the library and call your functions. It says it's significantly slower than JNI, which makes sense because everything's dynamically loaded, but i noticed no performance hits.
For figuring out how the C compilers mangle your function names – turning strlen
into _strlen@4
or something – i recommend DLL Export Viewer (the download link is near the bottom). I don't know if Linux has a similar tool.
Alden
Updated on June 04, 2022Comments
-
Alden almost 2 years
I'm trying to write a simple Java program that calls a C function via JNI to print "Hello World". Everything compiles with no errors, but when I run the program I get an "UnsatisfiedLinkError: Can't find dependent libraries".
According to Dependency Walker and dumpbin, the only dependency is "kernel32.dll", in C:\Windows\System32 and its dependencies, also in System32.
Calling
System.loadLibrary("Kernel32");
returns with no error, but loading the Hello.dll that contains the printing function still throws an error.
Does anyone know what could be causing this?
EDIT:
Dependency Walker does give two warnings/errors:
-Error: At least one module has an unresolved import due to a missing export function in an implicitly dependent module.
-Error: Modules with different CPU types were found.
EDIT:
Here's some more details: I'm running Windows 7 64-bit, and compiling my .dll with cl (Visual Studio 2010).
My Java code Hello.java:
public class Hello { public static native void hello(); public static void main(String[] args) { hello(); } static { // Extra dependencies load with no error System.loadLibrary("NTDLL"); System.loadLibrary("KERNELBASE"); System.loadLibrary("KERNEL32"); System.loadLibrary("Hello"); // Throws UnsatisfiedLinkError } }
I can compile the java file with no error, and use javah -jni to generate a C header Hello.h:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class Hello */ #ifndef _Included_Hello #define _Included_Hello #ifdef __cplusplus extern "C" { #endif /* * Class: Hello * Method: hello * Signature: ()V */ JNIEXPORT void JNICALL Java_Hello_hello (JNIEnv *, jclass); #ifdef __cplusplus } #endif #endif
I implement the header in Hello.c:
#include <stdio.h> #include <jni.h> #include "Hello.h" #pragma comment(linker, "/EXPORT:Java_Hello_hello=_Java_Hello_hello@8") JNIEXPORT void JNICALL Java_Hello_hello(JNIEnv* env, jclass class) { printf("Hello World\n"); return; }
The C code is compiled with cl (though I have also tried tcc) into Hello.dll, which is stored in the same directory as the java .class
-
Alden over 11 yearsI have looked at how to fix the name mangling here but I will take a look at JNA. Thanks.
-
likejudo over 10 yearsJNA is not free for commercial use