【问题标题】:How to resolve UnsatisfiedLinkError when using JNI with packages?将 JNI 与包一起使用时如何解决 UnsatisfiedLinkError?
【发布时间】:2017-06-08 15:40:32
【问题描述】:

首先,我的示例目录结构如下:

Sample.c
lib/
mypackage/
--Sample.java

mypackage 中的Sample.java 看起来像这样:

package mypackage;

public class Sample {
    public static native int sampleMethod(int x);

    public static void main(String[] args) {
        System.loadLibrary("Sample");
        System.out.println("sampleMethod result: " + sampleMethod(5));
    }
}

我运行javac mypackage/Sample.java 来编译java 文件和javah mypackage.Sample 来生成JNI 头文件。然后我使用以下命令编译库:

clang -I"${JAVA_HOME}/include" -I"${JAVA_HOME}/include/darwin" -o lib/libSample.so -shared Sample.c

此时目录结构如下:

Sample.c
mypackage_Sample.h
lib/
--libSample.so
mypackage/
--Sample.java
--Sample.class

现在,当我尝试使用 java -Djava.library.path=./lib/ mypackage.Sample 运行示例时,出现以下错误:

Exception in thread "main" java.lang.UnsatisfiedLinkError: no Sample in java.library.path
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867)
    at java.lang.Runtime.loadLibrary0(Runtime.java:870)
    at java.lang.System.loadLibrary(System.java:1122)
    at mypackage.Sample.main(Sample.java:7)

我尝试指定lib/ 的完整路径,但我得到了同样的错误。

我不确定标头的代码和实现是否重要,但无论如何我都会发布它们。

mypackage_Sample.h:

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

#ifndef _Included_mypackage_Sample
#define _Included_mypackage_Sample
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     mypackage_Sample
 * Method:    sampleMethod
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_mypackage_Sample_sampleMethod
  (JNIEnv *, jclass, jint);

#ifdef __cplusplus
}
#endif
#endif

Sample.c:

#include "mypackage_Sample.h"
#include <stdio.h>

JNIEXPORT jint JNICALL Java_mypackage_Sample_sampleMethod
  (JNIEnv * env, jclass obj, jint num) {
      return num * num;
  }

我使用clang 7.0.2java 1.8.0_101OS X Yosemite 10.10.5 上运行此程序。

【问题讨论】:

  • 您可能有错误的库名称,您可以通过System.mapLibraryName("Sample"); 找到您需要的内容。我认为在 OSX 上应该是 Sample.dylib,而不是 libSample.so
  • 好的,我不知道,它解决了这个问题。它是libSample.dylib。你可以把它写成答案。
  • 完成,(我可能一开始就应该这样做:)。)

标签: java c java-native-interface unsatisfiedlinkerror


【解决方案1】:

您的库文件中的名称似乎有误 (libSample.so)。

如果你使用:

System.loadLibrary("Sample");

JVM 会将此名称映射到特定于平台的文件名以尝试加载。在 Linux 上是 libSample.so,在 Windows 上是 Sample.dll,但在 OS X 上是别的东西。

您可以通过查看以下输出来找出您的库文件应具有的名称:

System.mapLibraryName("Sample");

在目标平台上调用。

之后,您可以将其用作库文件的名称。

【讨论】:

  • 再次感谢您!我被一篇文章迷惑了,该文章指出所有基于UNIX 的系统的库名称都是lib&lt;name&gt;.somapLibraryName 确实解决了这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-05-05
  • 1970-01-01
  • 2015-10-23
  • 1970-01-01
  • 1970-01-01
  • 2021-10-14
  • 2019-07-11
相关资源
最近更新 更多