当前位置: 首页 > 知识库问答 >
问题:

GraalVM Java on truffle-NullPointerException from NFIContext。执行Java代码时获取后端

越俊驰
2023-03-14

我正在尝试使用GraalVM的Truffle在java应用程序中动态运行java代码。没有成功。

我正在开发MacOs 11.5.2。

我跟进了GraalVM JDK安装过程,并使用gu install espresso安装了espresso。

$ java -version
openjdk version "11.0.13" 2021-10-19
OpenJDK Runtime Environment GraalVM CE 21.3.0 (build 11.0.13+7-jvmci-21.3-b05)
OpenJDK 64-Bit Server VM GraalVM CE 21.3.0 (build 11.0.13+7-jvmci-21.3-b05, mixed mode, sharing)
$ java -truffle -version
openjdk version "11.0.13" 2021-10-19
OpenJDK Runtime Environment GraalVM CE 21.3.0 (build 11.0.13+7-jvmci-21.3-b05)
Espresso 64-Bit VM GraalVM CE 21.3.0 (build 11-espresso-21.3.0, mixed mode)

我已经能够运行一个简单的Hello世界级和Jar。甚至在java主机应用程序中运行javascript代码(作为字符串)。

但当我试图执行这个程序时,我得到了一个错误:

package com.host;

import java.io.IOException;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Value;

public class Main {
  public static void main(String[] args) throws IOException {
    Context polyglot = Context.newBuilder("java").allowAllAccess(true).build();

    Value java_lang_Math = polyglot.getBindings("java").getMember("java.lang.Math"); // <- Faulty line
    double sqrt2 = java_lang_Math.invokeMember("sqrt", 2).asDouble();
    double pi = java_lang_Math.getMember("PI").asDouble();
    System.out.println(sqrt2);
    System.out.println(pi);
  }
}

顺便说一下,这段代码来自他们的doc(https://www.graalvm.org/reference-manual/java-on-truffle/interoperability/#embedding-in-host-java)

但当我试图以类或Jar的形式执行代码时,我会遇到以下错误:

$ java -jar target/host-code-1.0-SNAPSHOT.jar
Exception in thread "main" org.graalvm.polyglot.PolyglotException: java.lang.NullPointerException
    at com.oracle.truffle.nfi.NFIContext.getBackend(NFIContext.java:83)
    at com.oracle.truffle.nfi.NFIRootNode.execute(NFIRootNode.java:147)
    at org.graalvm.sdk/org.graalvm.polyglot.Context.getBindings(Context.java:540)
    at com.host.Main.main(Main.java:13)
Original Internal Error:
java.lang.NullPointerException
    at com.oracle.truffle.nfi.NFIContext.getBackend(NFIContext.java:83)
    at com.oracle.truffle.nfi.NFIRootNode.execute(NFIRootNode.java:147)
    at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.executeRootNode(OptimizedCallTarget.java:650)
    at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.profiledPERoot(OptimizedCallTarget.java:622)
    at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callBoundary(OptimizedCallTarget.java:555)
    at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.doInvoke(OptimizedCallTarget.java:539)
    at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callIndirect(OptimizedCallTarget.java:463)
    at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.call(OptimizedCallTarget.java:444)
    at com.oracle.truffle.espresso.ffi.nfi.NFINativeAccess.loadLibraryHelper(NFINativeAccess.java:180)
    at com.oracle.truffle.espresso.ffi.nfi.NFISulongNativeAccess.loadLibrary(NFISulongNativeAccess.java:44)
    at com.oracle.truffle.espresso.ffi.NativeAccess.loadLibrary(NativeAccess.java:77)
    at com.oracle.truffle.espresso.jni.JniEnv.<init>(JniEnv.java:316)
    at com.oracle.truffle.espresso.jni.JniEnv.create(JniEnv.java:364)
    at com.oracle.truffle.espresso.runtime.EspressoContext.getJNI(EspressoContext.java:685)
    at com.oracle.truffle.espresso.runtime.EspressoContext.spawnVM(EspressoContext.java:463)
    at com.oracle.truffle.espresso.runtime.EspressoContext.initializeContext(EspressoContext.java:423)
    at com.oracle.truffle.espresso.EspressoLanguage.initializeContext(EspressoLanguage.java:144)
    at com.oracle.truffle.espresso.EspressoLanguage.initializeContext(EspressoLanguage.java:64)
    at org.graalvm.truffle/com.oracle.truffle.api.TruffleLanguage$Env.postInit(TruffleLanguage.java:3606)
    at org.graalvm.truffle/com.oracle.truffle.api.LanguageAccessor$LanguageImpl.postInitEnv(LanguageAccessor.java:301)
    at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotLanguageContext.ensureInitialized(PolyglotLanguageContext.java:661)
    at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotContextImpl.getBindings(PolyglotContextImpl.java:969)
    at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotContextDispatch.getBindings(PolyglotContextDispatch.java:97)
    at org.graalvm.sdk/org.graalvm.polyglot.Context.getBindings(Context.java:540)
    at com.host.Main.main(Main.java:13)
Caused by: Attached Guest Language Frames (1)

我不知道我错过了什么,也不知道如何解决这个问题。有人有主意吗?

共有1个答案

常智勇
2023-03-14

松露上的Java(浓缩咖啡)有不同的配置:原生和JVM,单/多上下文。。。它至少以一种配置在所有主要操作系统上运行,但不是所有操作系统都运行。

Espresso native(无热点),单一上下文,可在所有平台上运行。目前,HotSpot和/或multi-context上的浓缩咖啡仅在Linux上运行,这适用于文档中的一些示例。

要在HotSpot上运行浓缩咖啡,主要挑战之一是隔离本地库。在Linux上,Espresso依赖glibc的dlmopen在隔离链接名称空间中加载本机库,这允许加载同一个库两次或更多次,而且在加载例如libjava时,我们希望有一个针对Espresso的libjvm而不是HotSpot的新副本链接。

我们还没有在Mac或Windows上找到类似的隔离机制,尽管Android上存在替代方案。

为了克服这一局限性,该团队正在积极开发一款苏龙本地浓缩咖啡后端。Sulong是GraalVM的高性能LLVM位码解释器。其想法是将OpenJDK本机库编译为LLVM位代码,并在Sulong上加载/运行它们,Sulong在设计上支持隔离;已经有了一个工作原型。

在当前状态下,Espresso在默认情况下会尝试在MacOS上使用Sulong原生后端,但它还没有完全运行/发布,因此会出现错误。

 类似资料:
  • 问题内容: 我想测量在Python程序中评估一块代码所花费的时间,可能在用户cpu时间,系统cpu时间和经过时间之间进行区分。 我知道该模块,但是我有许多自写函数,在设置过程中传递它们并不是很容易。 我宁愿有一些可以使用的东西: 用户和系统的CPU时间不是必需的(尽管我想测量它们),但是对于过去的时间,我希望能够执行类似的操作,而不是使用复杂的命令或模块。 问题答案: 要获取以秒为单位的经过时间,

  • 我想和JDA做一个不和谐的赠品机器人。对我来说,在文件或其他地方保存条目是没有问题的,但是如何在3天后选择获胜者呢?它听起来不是很有效,使用定时器任务或保存到一个文件中的日期,并检查它每发送消息? 你不需要给我一个代码示例,但是一个简短的解释就足够了

  • 问题内容: 我有一个包含以下内容的字符串: 我可以在Java中执行此字符串中的代码吗? 问题答案: 从Java 6开始,您 可以 使用SDK中的标准API 编译并运行定义为字符串或文件的Java 编译单元 (编译单元基本上是.java文件中的所有内容-包,导入,类/接口/枚举),看看这个例子。但是,您 不能 像问题中那样运行任意Java代码段。 如果可能的话,最好嵌入一种不同的脚本语言,该脚本语言

  • 您可以使用Ant来执行Java代码。 在以下示例中,java类接受参数(管理员的电子邮件地址)并发送电子邮件。 public class NotifyAdministrator { public static void main(String[] args) { String email = args[0]; notifyAdministratorviaEmail(e

  • 我有一个代码如下: 当我尝试运行代码时,我得到这样的消息: 我提到了这个链接,但不明白如何修改上面的代码,使其可行:例外:需要mockito,但没有调用,实际上与这个mock没有任何交互 有人能帮忙吗。 通过添加c.getResult(新的A(新的B()),新的F())解决了上述错误;在上面 我错过了什么?我一直在使用的课程:

  • 我认为两个线程同时调用take方法,只有一个线程可以成功地获得锁,而另一个线程将在以下行等待锁:这是take的源代码: 但是,当我对这两个线程进行线程转储时,我发现两个线程都成功锁定,并且在线等待:(因为队列为空)这是线程转储: “test-thread-18”#6357守护进程prio=5 os_prio=0 tid=0x00007f8f54543000 nid=0x58ef在条件[0x0000