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

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

问题描述

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

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

这就是我使用它的方式:

This is how I'm using it:

<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

按照这种方法,我可以创建 libHScode.so libjniHScode.so 使用 javacpp ,运行正常with:

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



现在,以下步骤是我想要在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.

但是,如果我从 HScode.jar > build 上面的文件夹,这样我的jar包含 libjniHScode.so libHScode.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 从那里加载它们。因此,当通过其他方式构建本机库时,仍然需要将它们移动到 com / example / linux-x86_64 / ,无论是在JAR文件内还是在外部作为普通文件,如果我们想要 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天全站免登陆