问题
I'm trying to use JNI and getting java.lang.UnsatisfiedLinkError. Unlike the other million questions asked about this, I have the lib on my path, and have even seen the exception change when I remove it. I'm sure that something is wrong with the dll I have created, but I'm not sure what.
Here is my java class code:
package com;
public class Tune {
static {
System.loadLibrary("lala");
}
public static void main(String[] args) {
Tune j = new Tune();
System.out.println("2+6="+j.add(2, 6));
}
native public int add(int x,int y);
}
Here is the abridged portion of my javah produced header file:
/*
* Class: com_Tune
* Method: add
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_Tune_add
(JNIEnv *, jobject, jint, jint);
Here is my c++ code:
#include <jni.h>
#include <com_Tune.h>
JNIEXPORT jint JNICALL Java_com_Tune_add
(JNIEnv * env, jobject obj, jint x, jint y) {
return x+y;
}
Here is the runtime exception I get from eclipse:
Exception in thread "main" java.lang.UnsatisfiedLinkError: com.Tune.add(II)I
at com.Tune.add(Native Method)
at com.Tune.main(Tune.java:9)
I read that the above exception means it DID find the library "lala", but that the method "add" is still not defined. The only things I see different between my project and the tutorial are:
- Mine uses a package, instead of the default package (shouldn't tutorials really do this?!?! come on let's get professional)
- Mine has a return value.
- I moved my dll after it was created (I don't think this will break it since my path is configured.)
How is this possible?
Other Info:
OS: Windows 7
JDK: 1.6.0_31 (for x86, 32 bit jvm)
C++ IDE: Code::Blocks (the dll was compiled automatically by the Code::Blocks IDE)
C++ compiler: MinGW32-g++ (the GNU C++ compiler)
I have jni.h and com_Tune.h in C:\_\include
I have lala.dll in C:\_\lib
Environment Variables:
PATH: C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;%CommonProgramFiles%\Microsoft Shared\Windows Live;C:\Program Files (x86)\AMD APP\bin\x86_64;C:\Program Files (x86)\AMD APP\bin\x86;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static;C:\Apps;%JAVA_HOME%\bin;C:\Program Files\MySQL\MySQL Server 5.5\bin;%MAVEN_HOME%\bin;%HADOOP_INSTALL%\bin;c:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\;c:\Program Files\Microsoft SQL Server\100\Tools\Binn\;c:\Program Files\Microsoft SQL Server\100\DTS\Binn\;C:\MinGW\bin;C:\Program Files (x86)\GnuWin32\bin;C:_\path;C:\_\lib;C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin;C:\_\include
回答1:
Just guessing... Is your dll depends on another dll that is not on the path? MinGW modules usually depend on specific C runtime library.
回答2:
The problem is with the name compiler has generated: Java_com_Tune_add@16
Use either of two
gcc -Wl,-kill-at
Or
gcc -Wl,--add-stdcall-alias
This will ensure generation of Java_com_Tune_add
And then your method call will be successful.
回答3:
One possible source of the problem might be that you compiled the code using a C++ compiler, which uses a different [calling convention] than plain C. If thats the case then the solution would be to wrap the code for the method in a extern "C"
block like this:
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jint JNICALL Java_com_Tune_add
...
#ifdef __cplusplus
}
#endif
回答4:
I had the same issue and the flag -Wl,-kill-at worked for me.
回答5:
Try with following example for Windows: (remember that the Java class name must be the same that corresponding file name)
Step 1. Create the following Java file (P.java):
class P
{
static
{
// "P" is the name of DLL without ".dll"
System.loadLibrary ("P");
}
public static native void f(int i);
public static void main(String[] args)
{
f(1);
}
}
Step 2. javac P.java
Step 3. javah P
Then, "javah" generates the header file "P.h"
Step 4. Create the file "P.def" including the following two lines (this file defines the exported symbols, in this case the name of C function):
EXPORTS
Java_P_f
Step 5. Create your C file (P.c):
#include "P.h"
JNIEXPORT void JNICALL Java_P_f(JNIEnv *env, jclass c, jint i)
{
printf("%i\n",i);
}
Step 6. Within Visual Studio command promt, define the following variables:
set JAVA_HOME= the path of JDK
set include=%include%;%JAVA_HOME%\include;%JAVA_HOME%\include\win32
Step 7. Generate DLL:
cl /LD P.c P.def
Step 8. Run the Java program:
java P
(Note: P.dll and P.class are located in the same directory)
来源:https://stackoverflow.com/questions/9367700/jni-library-is-found-on-path-but-method-is-not-java-lang-unsatisfiedlinkerror