JavaCPP,在JAR中归档本机库时出现UnsatisfiedLinkError [英] JavaCPP, UnsatisfiedLinkError when native library is archived in JAR
问题描述
我正在尝试使用 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屋!