使用GraalVM中的本机映像的Java调用C库

时间:2020-07-08 09:56:25

标签: java graalvm graalvm-native-image

我有一个简单的项目:https://github.com/MarcoLunar/native-pid-test 它所做的只是从C库调用getpid。项目很简单:

public static void main(String[] args) throws Exception {
    System.out.println("start");
    C_lib cLib = Native.loadLibrary("c", C_lib.class);
    int getpid = cLib.getpid();
    System.out.println("pid = " + getpid);
    System.out.println("end");
  }

从IDE启动时,一切正常:

start
pid = 155080
end

当尝试使用GraalVM中的本机映像进行构建时,出现此错误:

[simpletest:155323]      compile:   2,597.81 ms,  2.05 GB
Fatal error:org.graalvm.compiler.graph.GraalGraphError: java.lang.NullPointerException
        at node: 43|&
        at method: Object com.oracle.svm.reflect.JNIGeneratedMethodSupport_getFieldOffsetFromId_5041c78d77a7b3d62103393b72fc35d80d2cc709.invoke(Object, Object[])
        at org.graalvm.compiler.phases.common.CanonicalizerPhase$Instance.tryCanonicalize(CanonicalizerPhase.java:397)
        at org.graalvm.compiler.phases.common.CanonicalizerPhase$Instance.processNode(CanonicalizerPhase.java:325)
        at org.graalvm.compiler.phases.common.CanonicalizerPhase$Instance.processWorkSet(CanonicalizerPhase.java:302)
        at org.graalvm.compiler.phases.common.CanonicalizerPhase$Instance.run(CanonicalizerPhase.java:264)
        at org.graalvm.compiler.phases.common.CanonicalizerPhase.run(CanonicalizerPhase.java:177)
        at org.graalvm.compiler.phases.common.CanonicalizerPhase.run(CanonicalizerPhase.java:73)
        at org.graalvm.compiler.phases.BasePhase.apply(BasePhase.java:214)
        at org.graalvm.compiler.phases.BasePhase.apply(BasePhase.java:147)
        at com.oracle.svm.hosted.code.CompileQueue.doInlineTrivial(CompileQueue.java:587)
        at com.oracle.svm.hosted.code.CompileQueue.access$000(CompileQueue.java:156)
        at com.oracle.svm.hosted.code.CompileQueue$TrivialInlineTask.run(CompileQueue.java:284)
        at com.oracle.graal.pointsto.util.CompletionExecutor.lambda$execute$0(CompletionExecutor.java:173)
        at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1402)
        at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
        at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
        at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
        at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Caused by: java.lang.NullPointerException
        at org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.tryConstantFold(BinaryArithmeticNode.java:120)

我已经尝试了很多次,有很多不同的解决方案……但是到目前为止,我没有更多要检查的了。 我正在寻求有关修复项目的帮助。我认为这是可能的,因为在某些配置下,我的错误与https中的错误相同://github.com/oracle/graal/issues/2261 ...某人对其进行了修复...但未编写解决方案: (

1 个答案:

答案 0 :(得分:1)

我认为目前JNA不能以本机图像运行。如果可能的话,您可以使用JNI。或者,您可以使用另一个接口来处理将在本机映像中专门工作的本机代码。可以在org.graalvm.nativeimage.c的javadoc及其子包中找到一些信息:https://www.graalvm.org/sdk/javadoc/index.html?org/graalvm/nativeimage/c/package-summary.html 这是使用它的示例:https://www.praj.in/posts/2020/opengl-demo-using-graalvm/