将 Nashorn 迁移到 GraalVM
Migrate Nashorn to GraalVM
我正在使用来自 OpenJDK 12 的 Nashorn JS 引擎。Nashorn 似乎已被弃用。我正在寻找哪些是可用的替代品。我找到了 GraalVM,但我不确定这是否是最好的。
如何从 Java 执行 GraalVM JavaScript ?你有什么例子吗?
Nashorn 使用的是 Java:
NashornScriptEngineFactory nsef = new NashornScriptEngineFactory();
ScriptEngine engine = nsef.getScriptEngine( BasicDBObject.class.getClassLoader() );
final Bindings binding = engine.getContext().getBindings(ScriptContext.ENGINE_SCOPE);
在 Nashorn 中,我创建了一个扩展 AbstractJSObject 的 WrappedMongoDatabase。我在那里添加了一些 'virtual' 方法来模拟 MongoDB 查询语言,例如 getCollection('persons').find()...
你知道在 GraalVM 中替换 AbstractJSObject 的方法吗?
我查看了 ProxyObject,不知何故我找不到像 AbstractJSObject 中那样覆盖调用(Object thiz,Object...args)的方法。
public class WrappedMongoDatabase extends AbstractJSObject {
@Override
public boolean hasMember(String name) {
return "getCollection".equals( name ) || "createCollection".equals(name)||...;
}
@Override
public Object getMember(final String name) {
if ( hasMember( name ) ){
return new AbstractJSObject() {
@Override
public Object call(Object thiz, Object... args) {
switch( name ) {
case "getCollection":
if (args.length == 1 && args[0] instanceof String) {
return getCollection((String) args[0]);
}
break;
...
}
}
}
}
}
}
ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
bindings.put("polyglot.js.allowHostAccess", true);
bindings.put("polyglot.js.allowHostClassLookup", (Predicate<String>) s -> true);
bindings.put("javaObj", new Object());
engine.eval("(javaObj instanceof Java.type('java.lang.Object'));"); // would not work without allowHostAccess and allowHostClassLookup
注意nashorn兼容模式:
These options control the sandboxing rules applied to evaluated JavaScript code and are set to false by default, unless the application was started in Nashorn compatibility mode (--js.nashorn-compat=true).
GraalVM 是一个不错的选择。我们已经使用它一段时间了,它运行良好,JavaScript 实现比 Nashorn(或 Rhino)好得多。特别是,它符合 ECMA2020,它支持 Node 要求(那是巨大的!),它表现得更好,等等......
如果您使用的是 Nashorn,GraalVM 是向前迈出的一大步,但它确实需要一些调整,这些调整在 GraalVM documentation.
我正在使用来自 OpenJDK 12 的 Nashorn JS 引擎。Nashorn 似乎已被弃用。我正在寻找哪些是可用的替代品。我找到了 GraalVM,但我不确定这是否是最好的。 如何从 Java 执行 GraalVM JavaScript ?你有什么例子吗?
Nashorn 使用的是 Java:
NashornScriptEngineFactory nsef = new NashornScriptEngineFactory();
ScriptEngine engine = nsef.getScriptEngine( BasicDBObject.class.getClassLoader() );
final Bindings binding = engine.getContext().getBindings(ScriptContext.ENGINE_SCOPE);
在 Nashorn 中,我创建了一个扩展 AbstractJSObject 的 WrappedMongoDatabase。我在那里添加了一些 'virtual' 方法来模拟 MongoDB 查询语言,例如 getCollection('persons').find()... 你知道在 GraalVM 中替换 AbstractJSObject 的方法吗?
我查看了 ProxyObject,不知何故我找不到像 AbstractJSObject 中那样覆盖调用(Object thiz,Object...args)的方法。
public class WrappedMongoDatabase extends AbstractJSObject {
@Override
public boolean hasMember(String name) {
return "getCollection".equals( name ) || "createCollection".equals(name)||...;
}
@Override
public Object getMember(final String name) {
if ( hasMember( name ) ){
return new AbstractJSObject() {
@Override
public Object call(Object thiz, Object... args) {
switch( name ) {
case "getCollection":
if (args.length == 1 && args[0] instanceof String) {
return getCollection((String) args[0]);
}
break;
...
}
}
}
}
}
}
ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE); bindings.put("polyglot.js.allowHostAccess", true); bindings.put("polyglot.js.allowHostClassLookup", (Predicate<String>) s -> true); bindings.put("javaObj", new Object()); engine.eval("(javaObj instanceof Java.type('java.lang.Object'));"); // would not work without allowHostAccess and allowHostClassLookup
注意nashorn兼容模式:
These options control the sandboxing rules applied to evaluated JavaScript code and are set to false by default, unless the application was started in Nashorn compatibility mode (--js.nashorn-compat=true).
GraalVM 是一个不错的选择。我们已经使用它一段时间了,它运行良好,JavaScript 实现比 Nashorn(或 Rhino)好得多。特别是,它符合 ECMA2020,它支持 Node 要求(那是巨大的!),它表现得更好,等等......
如果您使用的是 Nashorn,GraalVM 是向前迈出的一大步,但它确实需要一些调整,这些调整在 GraalVM documentation.