GraalVM - 在没有上下文的情况下使用多语言值

标签 graalvm

我正在 Graal 上编写一个应用程序,它将能够执行不同语言的小脚本。

我正在尝试为我用来将 Context.eval() 调用(类型:Value)的结果转换/处理为 Java 对象的类编写一些单元测试。我从文档中知道一个 Value 实例总是绑定(bind)到一个上下文,所以当我尝试写这样的东西时:

@Test
public void NumericFloatTest() throws ScriptExecutionException {

    GuestLanguageResultProcessor LangProcessor = new GuestLanguageResultProcessor();
    Float javaValue = (float) 43.25;
    Value numValue = Value.asValue(javaValue);
    LangProcessor.processResult(numValue);

    Object result = LangProcessor.processResult(numValue);

    assertThat(result.getClass()).isEqualTo(Float.class);
}

我收到以下错误:

java.lang.IllegalStateException: No current context is available. Make sure the Java method is invoked by a Graal guest language or a context is entered using Context.enter().

我想从概念上讲,拥有一个没有关联的访客代码位的“值”实例是没有意义的,所以我的问题是:

如何着手测试我的 GuestLanguageResultProcessor 类?我是否必须通过创建上下文来“膨胀”我的单元测试?

专家的附带问题:我还使用此类 (GuestLanguageResultProcessor) 从多语言值实例中提取 Java 值,以便我可以关闭上下文。换句话说,在我看来,在能够执行 Context.close() 之前,我需要调用 [value instance].asString() 或 .asWhatever() 才能得到结果并能够在不关闭上下文的情况下关闭上下文如 docs 中所述获得 IllegalStateException .

我做的对吗?有没有更好的方法来处理获取结果和安全关闭上下文?

谢谢!

最佳答案

How can I go about testing my GuestLanguageResultProcessor class? Do I have to "bloat" my unit test with the creation of a context?

我担心有点腹胀是必要的。我建议使用以下代码来使您的测试工作。这也可以在测试基类中完成,以避免重复。

Context context;

@Before
public void setup() {
    context = Context.create();
    context.enter();
}

@After
public void setup() {
    context.leave();
    context.close();
}

@Test
public void NumericFloatTest() throws ScriptExecutionException {
    GuestLanguageResultProcessor LangProcessor = new GuestLanguageResultProcessor();
    Float javaValue = (float) 43.25;
    Value numValue = Value.asValue(javaValue);
    LangProcessor.processResult(numValue);

    Object result = LangProcessor.processResult(numValue);

    assertThat(result.getClass()).isEqualTo(Float.class);
}

Am I doing it right? Is there a better way to handle getting the result and closing the context safely?

值实例可能会绑定(bind)到 guest 语言对象,例如 JavaScript 对象,一旦上下文关闭,这些对象就会失效。并非总是可以将客户语言对象转换为永久性 Java 表示。例如,多语言值可能指的是整个 JavaScript 对象图。

如果可能,我建议只要需要值就保持上下文打开,因为它不需要任何转换。

如果那是不可能的,并且您只处理基元和数组,您可以尝试使用以下方法。您还可以尝试通过访问其成员将对象复制到 Java 领域。

Object copyToJavaLand(Value value) {
    if (value.isBoolean()) {
        return value.asBoolean();
    } else if (value.isString()) {
        return value.asString();
    } else if (value.isNumber()) {
        return value.as(Number.class);
    } else if (value.isHostObject()) {
        return value.asHostObject();
    } else if (value.isProxyObject()) {
        return value.asProxyObject();
    } else if (value.hasArrayElements()) {
        Object[] array = new Object[(int) value.getArraySize()];
        for (int i = 0; i < array.length; i++) {
            array[i] = copyToJavaLand(value.getArrayElement(i));
        }
        return array;
    }
    throw new IllegalArgumentException("Cannot copy value " + value + ".");
}

请注意,此方法并不总是安全的。例如,如果数组引用自身,此方法将因堆栈溢出错误而崩溃。

关于GraalVM - 在没有上下文的情况下使用多语言值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51669154/

相关文章:

windows - 适用于 Windows 的 GraalVM

java - Swing 应用程序的 Graal native 图像 : Detected a started Thread in the image heap

windows - 有没有办法使用 GraalVM 从 Jetpack Compose 桌面应用程序创建 native 二进制文件?

java - Quarkus 使用 -Dnative-image.docker-build=true 构建 native 可执行文件 NoSuchFileException

java - 递归程序执行期间出现 Truffle 语言运行时错误

java - GraalVM 应用程序可以部署在 "regular"VM 上吗

java - 使用 graal python 从 java 获取外部环境参数

javascript - 将全局函数/变量添加到 GraalVM JavaScript 引擎

javascript - 如何将 sourcemaps 添加到 GraalVM JS 检查中?

java - 在 GraalVM 中安装 R 包的问题