运行 来自 Java 代码的 GraalVM 本机图像中的 JS 脚本
Running JS script from Java code in GraalVM native-image
我正在 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);
}
JS 代码只是尝试通过调用方法来使用 response
对象,例如:
print("Status code: " + response.getStatusCode());
这在 GraalVM 中 运行 时有效,但在创建本机图像时失败并出现此错误:
INVOKE on JavaObject[...] failed due to: Message not supported: INVOKE
如果我只是像 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)
我正在使用的原生图像命令:
native-image --language:js --report-unsupported-elements-at-runtime -jar my.jar
更新:从 RC 13 开始,现在支持使用本机图像进行反射访问。您需要为原生图像提供反射配置。
不幸的是,从 RC5 开始,GraalVM 在使用本机图像编译时还不支持 Java 对象的反射访问。我们计划在下一个候选版本中支持这一点。
作为临时解决方法,您可以像这样使用代理 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());
}
代理 API 允许模仿来宾语言值。
这是另一个代理示例:http://www.graalvm.org/docs/graalvm-as-a-platform/embed/#computed-arrays-using-polyglot-proxies
代理 Java文档:http://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/proxy/package-summary.html
我正在 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);
}
JS 代码只是尝试通过调用方法来使用 response
对象,例如:
print("Status code: " + response.getStatusCode());
这在 GraalVM 中 运行 时有效,但在创建本机图像时失败并出现此错误:
INVOKE on JavaObject[...] failed due to: Message not supported: INVOKE
如果我只是像 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)
我正在使用的原生图像命令:
native-image --language:js --report-unsupported-elements-at-runtime -jar my.jar
更新:从 RC 13 开始,现在支持使用本机图像进行反射访问。您需要为原生图像提供反射配置。
不幸的是,从 RC5 开始,GraalVM 在使用本机图像编译时还不支持 Java 对象的反射访问。我们计划在下一个候选版本中支持这一点。
作为临时解决方法,您可以像这样使用代理 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());
}
代理 API 允许模仿来宾语言值。
这是另一个代理示例:http://www.graalvm.org/docs/graalvm-as-a-platform/embed/#computed-arrays-using-polyglot-proxies
代理 Java文档:http://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/proxy/package-summary.html