Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JNI -- UnsatisfiedLinkError on native method

I'm running Windows XP. Apparently JNI and UnsatisfiedLinkError go hand in hand... I've noticed that most of the time, the linker error looks like this:

java.lang.UnsatisfiedLinkError: no whatever.dll in java.library.path

But that's not my problem; Java can find my DLL. I'm getting an error that makes me think i named my method wrong:

java.lang.UnsatisfiedLinkError: NativeTest.nativemethod(lJava/lang/String;)Z

I've tried looking at a number of similar questions on StackOverflow like this one, this one, this one, this one, and this one, but none of these methods have worked. I also found this thread on the Ubuntu forums where it looks like the exact same problem i'm having, but the question asker didn't say how they fixed their own problem (which really sucks). All Google searches on this have given me an error the same as the java.library.path one.

Here is my actual code.

NativeTest.java

class NativeTest
    {

    public static native boolean nativemethod (String arg);

    public static void main (String[] args)
        {
        System.out.println(nativemethod("0123456789"));
        System.out.println(nativemethod("012"));
        }

    static { System.loadLibrary("NativeTest"); }

    }

NativeTest.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class NativeTest */

#ifndef _Included_NativeTest
#define _Included_NativeTest
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     NativeTest
 * Method:    nativemethod
 * Signature: (Ljava/lang/String;)Z
 */
JNIEXPORT jboolean JNICALL Java_NativeTest_nativemethod
  (JNIEnv *, jclass, jstring);

#ifdef __cplusplus
}
#endif
#endif

NativeTest.c

#include <jni.h>
#include <windows.h>
#include "NativeTest.h"

JNIEXPORT jboolean JNICALL Java_NativeTest_nativemethod
    (JNIEnv* Jenv, jclass Jref, jstring Jarg)
    {
    MessageBox(NULL, "text", "title", MB_OK);
    int len = (*Jenv)->GetStringLength(Jenv, Jarg);
    return (jboolean)(len > 5);
    }

In cmd.exe: (The gcc command is my hodgepodge of various commands i've found on the internet.)

>javac NativeTest.java

>javah -jni NativeTest

>gcc -shared -I<jdk_dir>\include -I<jdk_dir>\include\win32 -oNativeTest.dll NativeTest.c -lgdi32

>java -Djava.library.path=. NativeTest
Exception on thread "main" java.lang.UnsatisfiedLinkError: NativeTest.nativemethod(Ljava/lang/String;)Z
        at NativeTest.nativemethod(Native Method)
        at NativeTest.main(NativeTest.java:8)

>java NativeTest
Exception on thread "main" java.lang.UnsatisfiedLinkError: NativeTest.nativemethod(Ljava/lang/String;)Z
        at NativeTest.nativemethod(Native Method)
        at NativeTest.main(NativeTest.java:8)
like image 956
nuju Avatar asked Apr 23 '12 02:04

nuju


1 Answers

After messing around and googling to solve the same problem for half of the day, I have found that GCC does not generate DLLs where the JVM can resolve symbols. But one can pass the correct command line args to GCC and then it works:

See this MinGW post on the subject. One needs to pass "-D_JNI_IMPLEMENTATION_ -Wl,--kill-at" as additional flags. Don't know if all of them are needed or just the first bit.

like image 58
stippi Avatar answered Sep 21 '22 21:09

stippi