Java – JNI: UnsatisfiedLinkError: Can’t find dependent libraries

javajava-native-interface

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

Best Answer

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.

Related Topic