JavaCPP,在 JAR 中归档本机库时出现 UnsatisfiedLinkError [英] JavaCPP, UnsatisfiedLinkError when native library is archived in JAR

查看:54
本文介绍了JavaCPP,在 JAR 中归档本机库时出现 UnsatisfiedLinkError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从 Java 调用 Haskell 代码,使用 JavaCPP 来帮助创建必要的 JNI绑定,正如 this question 中所述.

I'm trying to call Haskell code from Java, using JavaCPP to help create the necessary JNI binding, as already discussed in this question.

这就是我的使用方式:

<rootdir>
  /javacpp.jar
  /build (destination of libraris)
  /src   (contains Haskell code)
  /com/example/HSCode.java (Java class to load and use native lib)

HScode.java的内容:

package com.example;

import org.bytedeco.javacpp.*;
import org.bytedeco.javacpp.annotation.*;
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;

@Platform(include={"<HsFFI.h>","HScode_stub.h"})
public class HScode {
    static { Loader.load(); }
    public static native void hs_init(int[] argc, @Cast("char***") @ByPtrPtr PointerPointer argv);
    public static native String code_hs(String text);

    public static void main(String[] args) throws FileNotFoundException {
        String s = new Scanner(new File("test.txt")).useDelimiter("\Z").next();
        hs_init(null, null);
        String s1 = code_hs(s);
        System.out.println(s1);
    }
}

编译:

cd <rootdir>
ghc --make -isrc -dynamic -shared -fPIC src/HScode.hs 
     -o build/libHScode.so -lHSrts-ghc7.8.4 -optl-Wl,-rpath,.
javac -cp javacpp.jar com/example/HScode.java
java -jar javacpp.jar -d build 
     -Dplatform.compiler=ghc -Dplatform.includepath="src:com/example" 
     -Dplatform.compiler.output="-optl-Wl,-rpath,. -optc-O3 -Wall build/libHScode.so -dynamic -fPIC -shared -lstdc++ -lHSrts-ghc7.8.4 -o " com.example.HScode

按照这种方法,我可以使用 javacpp 创建一个 libHScode.so 和一个 libjniHScode.so,它们运行良好:

Following this approach, I can create a libHScode.so and a libjniHScode.so using javacpp, which runs fine with:

$ java -cp javacpp.jar:. com.example.HScode

罐子

现在,接下来的步骤是我想将所有内容打包到一个 jar 中,并且能够从一个更大的 java 项目中使用这个 jar 的 com.example.HScode.

JavaCPP 的页面提及:

JavaCPP's page mentions:

[...] 此外,在运行时,Loader.load() 方法会自动从 Java 资源中加载本地库,这些资源位于正确的目录由构建过程.它们甚至可以存档在 JAR 文件中,它不会改变任何内容.用户根本不需要图了解如何让系统加载文件.

[...] Moreover, at runtime, the Loader.load() method automatically loads the native libraries from Java resources, which were placed in the right directory by the building process. They can even be archived in a JAR file, it changes nothing. Users simply do not need to figure out how to make the system load the files.

所以我认为这应该可行.

So I thought this should work.

但是,如果我从上面 build 文件夹的内容中制作了一个 jar HScode.jar,这样我的 jar 就同时包含 libjniHScode.solibHScode.so,然后运行它:

However, if I make a jar HScode.jar out of the content of the build folder above, so that my jar contains both libjniHScode.so and libHScode.so, and run it with:

$ java -cp javacpp.jar:HScode.jar:. com.example.HScode

然后它找不到我的本机代码(为匿名而编辑的异常):

then it cannot find my native code (exception edited for anonymization):

Exception in thread "main" java.lang.UnsatisfiedLinkError: no jniHScode in java.library.path
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1865)
    at java.lang.Runtime.loadLibrary0(Runtime.java:870)
    at java.lang.System.loadLibrary(System.java:1122)
    at org.bytedeco.javacpp.Loader.loadLibrary(Loader.java:597)
    at org.bytedeco.javacpp.Loader.load(Loader.java:438)
    at org.bytedeco.javacpp.Loader.load(Loader.java:381)
    at com.example.HScode.<clinit>(HScode.java:13)
Caused by: java.lang.UnsatisfiedLinkError: /compilation-path/linux-x86_64/libjniHScode.so: HScode.so: cannot open shared object file: No such file or directory
    at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1937)
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1822)
    at java.lang.Runtime.load0(Runtime.java:809)
    at java.lang.System.load(System.java:1086)
    at org.bytedeco.javacpp.Loader.loadLibrary(Loader.java:580)

我错过了什么?有谁知道 JavaCPP 在 jar 中存档时是否真的可以找到本机代码?

What am I missing? Does anyone know whether JavaCPP can actually find the native code when it's archived in a jar?

推荐答案

通过调用 javacpp -jar javacpp.jar com.example.HScode 构建原生库,将它们输出到 com/example/linux-x86_64/ 自动和 Loader 从那里加载它们.因此,当通过其他方式构建原生库时,如果我们想要 Loader 来找到它们.

Building for the native libraries by calling javacpp -jar javacpp.jar com.example.HScode outputs them in com/example/linux-x86_64/ automatically and the Loader loads them from there. So when building the native libraries by some other means, they still need to be moved to com/example/linux-x86_64/, whether inside a JAR file or outside as normal files, if we want the Loader to find them.

这篇关于JavaCPP,在 JAR 中归档本机库时出现 UnsatisfiedLinkError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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