javascript - 将 Nashorn 迁移到 GraalVM 以缓存和执行脚本
问题描述
所以我有一个 java 应用程序,它使用 NashornScriptEngine 创建一个 CompiledScript,然后我可以在其中创建一个 Invocable。编译后的脚本是从文件输入编译的,这是我要运行的 js。然后我将此 Invocable 缓存在地图中以供稍后执行。使用它就像
import javax.script.Invocable;
public void handleEvent(Event event, Processor processor){
try {
Invocable script = cache.get(event);
if(script != null) {
script.invokeFunction("run", data);
} else {
throw new UnsupportedOperationException(event.name());
}
} catch (Exception exception) ...
}
但是,由于 Nashorn 已被弃用,我试图在实现相同目标的同时切换到 GraalVM。我看到一些 GitHub 页面讨论了这个问题,但老实说并没有帮助我。这是我正在看的一些。
https://github.com/graalvm/graaljs/blob/master/docs/user/ScriptEngine.md https://github.com/graalvm/graaljs/issues/78
这是我发现最有用的,但是它不允许我像上面的代码那样在入口点调用,也不能创建一个可调用的缓存并稍后调用。
public void compile(File file){
try {
Source source = Source.newBuilder("js", file).build();
Engine engine = Engine.create();
Context context = Context.newBuilder("js").engine(engine).option("js.nashorn-compat", "true").build();
context.eval(source);
context.close();
} catch (Exception exception){
exceptionCaught(exception);
}
}
关于如何使用 GraalVM 将文件 (js) 编译为可调用对象的任何提示?谢谢!
解决方案
context.eval()
将返回一个类型的值org.graalvm.polyglot.Value
。当source
返回 afunction
时,此值将回答canExecute()
为true
,您可以value.execute(args...)
重复使用它。参见 Value 的 API:https ://www.graalvm.org/truffle/javadoc/org/graalvm/polyglot/Value.html
我看到你正在设置nashorn-compat
选项。请理解这是一个向后兼容的选项,您最好不要使用它。在许多情况下,如果没有该选项,您的代码将完美运行。请查看迁移指南以了解在 Nashorn 模式下可用的 GraalVM JavaScript 确实不支持某些内容的情况。
推荐阅读
- java - 如果使用枚举,如何清理代码太多
- ffmpeg - 尝试使用 ffmpeg 将多个视频与多个音频流连接起来
- android - 具有自定义数组列表的可扩展列表视图不显示子列表
- c# - 如何在另一个 UWP-App(在 Windows 10 下)的 Web 视图中显示 UWP-App?
- php - 两天后为 WooCommerce 保留订单发送自定义提醒电子邮件
- ms-access - 错误:- 对象“_global”的方法“范围”在同时运行 2 个函数时失败
- session - 如何在 JBoss 5 中通过会话 id 获取会话
- angularjs - 如何在angularjs中解码utf-16编码的字符串?
- amazon-web-services - 打包脚本错误 必须指定脚本文件或内联脚本
- android - 无法从 Android 中的 dataSnapShot 获取数据