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

时间:2015-09-24 06:25:51

标签: java java-native-interface unsatisfiedlinkerror

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

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

首先我编写了Class HelloJNI.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
   }
}

这节课我编译: 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类:

  • gcc -I“/ usr / lib / jvm / java-8-oracle / include”-I“/ usr / lib / jvm / java-8-oracle / include / linux”-c -Wall -Werror -fpic HelloJNI.c
  • gcc -shared -o hello.so HelloJNI.o

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

  • java -Djava.library.path =。 HelloJNI 这会产生错误:

    线程“main”中的异常java.lang.UnsatisfiedLinkError:java.library.path中没有问候     在java.lang.ClassLoader.loadLibrary(ClassLoader.java:1864)     在java.lang.Runtime.loadLibrary0(Runtime.java:870)     在java.lang.System.loadLibrary(System.java:1122)     在HelloJNI。(HelloJNI.java:3)

这似乎是互联网上最常见的JNI错误...我的方法名称似乎是正确的。我也跑了:

  • nm hello.so | grep说

这给了我: 00000000000006b0 T Java_HelloJNI_sayHello 这似乎是正确的,即编译器没有添加其他字符。我简单地用尽了我可以尝试的事情。有什么建议吗?

我的操作系统:Linux Mint 13,GCC 4.7.3版,java版本1.8.0_60

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

1 个答案:

答案 0 :(得分:3)

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

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