JNI UnsatisfiedLinkError 没有错误的方法名称和指定的库路径

JNI UnsatisfiedLinkError without wrong method names and with library path specified

我正在尝试按照本教程构建我的第一个 JNI 应用程序:https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html

问题摘要:运行我的应用程序运行时,出现 java.lang.UnsatisfiedLinkError 错误。

首先我写了ClassHelloJNI.java:

public class HelloJNI {
   static {
      System.loadLibrary("hello"); // Load native library at runtime
                                   // hello.dll (Windows) or libhello.so (Unixes)
   }

   // Declare a native method sayHello() that receives nothing and returns void
   private native void sayHello();

   // Test Driver
   public static void main(String[] args) {
      new HelloJNI().sayHello();  // invoke the native method
   }
}

这个 class 我编译的是: javac HelloJNI.java 接下来我运行javah HelloJNI 这产生了以下文件 HelloJNI.h:

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

#ifndef _Included_HelloJNI
#define _Included_HelloJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloJNI
 * Method:    sayHello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_HelloJNI_sayHello
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

接下来我实现了HelloJNI.c:

#include <jni.h>
#include <stdio.h>
#include "HelloJNI.h"

// Implementation of native method sayHello() of HelloJNI class
JNIEXPORT void JNICALL Java_HelloJNI_sayHello(JNIEnv *env, jobject thisObj) {
   printf("Hello World!\n");
   return;
}

最后我编译了c class:

这将生成文件 hello.so 和 HelloJNI.o。接下来我尝试 运行 代码:

这似乎是 Internet 上最常见的 JNI 错误...我的方法名称似乎是正确的。我也 运行:

这给了我:00000000000006b0 T Java_HelloJNI_sayHello 这似乎是正确的,即编译器没有添加额外的字符。我只是 运行 没有我可以尝试的想法。有什么建议吗?

我的 OS:Linux Mint 13,GCC 版本 4.7.3,java 版本 1.8。0_60

==========更新=============== 当我用 System.load("/usr0/home/jkinable/workspace/javaIDEA/jnitest/hello.so"); 替换 System.loadLibrary("hello"); 时,我的 HelloWorld 示例有效!但是,我不想使用绝对路径,所以我仍在寻找使用 System.loadLibrary("hello"); 的方法?有什么建议么?我也在不同的 linux 系统上尝试了 运行ning,但我遇到了同样的问题。

事实证明,问题是由于 unix/linux 平台上的一些命名约定造成的!使用时: System.loadLibrary("hello"); 该文件不应命名为 hello.so!相反,名称应该是 libhello.so。在 Windows 上,使用 hello.dll。我很惊讶 IBM 的 JNI 教程中没有提到这个问题:http://www.ibm.com/developerworks/java/tutorials/j-jni/j-jni.html

我不确定这个问题背后的合理性是什么。你为什么要在你的文件系统上加载一个应该命名为 libhello.so 的库 "hello"(而不是 hello.so)?