从GraalVM native-image中的Java代码运行JS脚本

Ren*_*ato 2 java graalvm

我正在尝试从GraalVM本机映像中的Java代码运行JS脚本.

Java代码如下所示:

try (Context context = Context.create("js")) {
    Value bindings = context.getBindings("js");
    bindings.putMember("response", response);
    bindings.putMember("UTF8", StandardCharsets.UTF_8);
    context.eval("js", script);
} catch (PolyglotException e) {
    error("Error: " + e, 10);
}
Run Code Online (Sandbox Code Playgroud)

JS代码只是response通过调用一个方法来尝试使用该对象,例如:

 print("Status code: " + response.getStatusCode());
Run Code Online (Sandbox Code Playgroud)

这在GraalVM中运行时有效,但在创建本机映像时,它会失败,并显示以下错误:

INVOKE on JavaObject[...] failed due to: Message not supported: INVOKE
Run Code Online (Sandbox Code Playgroud)

如果我只是打印对象print("Response: " + response);,它不会失败.但是,如果我尝试调用任何方法response,我会收到此错误(偶数toString()hashCode()).

还有什么我需要做的,或者这只是SubstractVM原生图像中的一个错误,目前?

我的GraalVM版本:

java version "1.8.0_172"
Java(TM) SE Runtime Environment (build 1.8.0_172-b11)
GraalVM 1.0.0-rc4 (build 25.71-b01-internal-jvmci-0.45, mixed mode)
Run Code Online (Sandbox Code Playgroud)

native-image命令我正在使用:

native-image --language:js --report-unsupported-elements-at-runtime -jar my.jar
Run Code Online (Sandbox Code Playgroud)

Chr*_*mer 5

不幸的是,从RC5开始,GraalVM在使用native-image编译时还不支持Java对象的反射访问.我们计划在下一个候选版本之一中支持这一点.

作为临时解决方法,您可以使用Proxy API,如下所示:

try (Context context = Context.create("js")) {
    Map<String, Object> myObject = new HashMap<>();
    myObject.put("foo", "bar");
    context.getBindings("js").putMember("hostObject", ProxyObject.fromMap(myObject));
    assert "bar".equals(context.eval("js", "hostObject.foo").asString());
    myObject.put("foo", "baz");
    assert "baz".equals(context.eval("js", "hostObject.foo").asString());
}
Run Code Online (Sandbox Code Playgroud)

Proxy API允许模仿客户语言值.

这是另一个代理示例:http://www.graalvm.org/docs/graalvm-as-a-platform/embed/#computed-arrays-using-polyglot-proxies

代理Javadoc:http://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/proxy/package-summary.html