JNI UnsatisfiedLinkError,没有错误的方法名称,并且指定了库路径 [英] JNI UnsatisfiedLinkError without wrong method names and with library path specified

查看:148
本文介绍了JNI UnsatisfiedLinkError,没有错误的方法名称,并且指定了库路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to work build my very first JNI application, following this tutorial: https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html

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

Problem Summary: While running my application, I get an java.lang.UnsatisfiedLinkError error.

首先,我编写了 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 :

This class I compiled with: javac HelloJNI.java Next I ran javah HelloJNI This produced the following file 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.接下来,我尝试运行代码:

This produces the files hello.so and HelloJNI.o. Next I try to run the code:

  • java -Djava.library.path =.你好JNI 产生错误:

  • java -Djava.library.path=. HelloJNI This produces the error:

线程"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)

Exception in thread "main" java.lang.UnsatisfiedLinkError: no hello in java.library.path at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1864) at java.lang.Runtime.loadLibrary0(Runtime.java:870) at java.lang.System.loadLibrary(System.java:1122) at HelloJNI.(HelloJNI.java:3)

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

This seems to be the most common JNI error on the internet... My method names seem to be correct. I also ran:

  • nm hello.so | grep说

这给了我: 00000000000006b0 T Java_HelloJNI_sayHello 这似乎是正确的,即编译器未添加其他字符.我简直没有办法尝试的想法.有什么建议吗?

This gives me: 00000000000006b0 T Java_HelloJNI_sayHello which seems to be correct, i.e. the compiler didn't add additional characters. I simply ran out of ideas of things I could try. Any suggestions?

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

My OS: Linux Mint 13, GCC version 4.7.3, java version 1.8.0_60

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

==========UPDATE=============== When I replace System.loadLibrary("hello"); by System.load("/usr0/home/jkinable/workspace/javaIDEA/jnitest/hello.so"); my HelloWorld example works! However, I don't want to use an absolute path so I'm still looking for a way to use System.loadLibrary("hello"); instead? Any suggestions? I've also tried running on a different linux system, but I get the same issue.

推荐答案

事实证明,问题是由于unix/linux平台上的某些命名约定引起的!使用时: System.loadLibrary("hello"); 该文件不应命名为hello.so!相反,该名称应为 libhello.so .在Windows上,使用hello.dll.我很惊讶在IBM的JNI教程中没有提到此问题:

It turns out that the problem is due to some naming convention on unix/linux platforms! When using: System.loadLibrary("hello"); the file should not be named hello.so! Instead, the name should be libhello.so. On Windows, use hello.dll. I'm surprised that this issue is not mentioned in IBM's JNI tutorial: http://www.ibm.com/developerworks/java/tutorials/j-jni/j-jni.html

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

I'm not sure what the rationality behind this issue is. Why would you load a library "hello" which should be named libhello.so on your filesystem (instead of hello.so)?

这篇关于JNI UnsatisfiedLinkError,没有错误的方法名称,并且指定了库路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆