我有一个Java 7项目,它大量使用Javascript来编写各种功能的脚本。到目前为止,我一直使用Rhino作为脚本引擎。我现在想转到Java 8,这也意味着我将用Nashorn替换Rhino。
Nashorn与Rhino的兼容性如何?我可以使用它作为一个临时的替代品,或者我可以期待我的一些脚本将不再工作,需要移植到新的引擎上吗?有没有Nashorn不支持的Rhino常用特性?
发布于 2014-03-20 04:33:20
一个问题是,Nashorn不再能够默认地使用importPackage(com.organization.project.package);将整个Java包导入到全局范围中
但是,有一个简单的解决方法:通过将这一行添加到脚本中,您可以启用Rhino的旧行为:
load("nashorn:mozilla_compat.js");我遇到的另一个问题是,在java和javascript之间传递数据时,某些类型转换的工作方式不同。例如,当您将Javascript数组传递给Java时到达的对象不能再被强制转换为List,但它可以被强制转换为Map<String, Object>。作为一种解决方法,您可以使用Java.to(array, Java.type("java.util.List"))将Javascript数组转换为Javascript代码中的Java List
发布于 2015-08-13 04:44:20
要在JDK8上使用importClass方法,我们需要添加以下命令:
load("nashorn:mozilla_compat.js");但是,此更改会影响JDK 7上的执行(JDK不支持load方法)。
为了保持两个SDK的兼容性,我添加了try/catch子句来解决这个问题:
try{
load("nashorn:mozilla_compat.js");
}catch(e){
}发布于 2014-04-09 19:07:15
当内部类被声明为private时,Nashorn不能访问该内部类,Rhino能够做到这一点:
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class Test {
public static void main(String[] args) {
Test test = new Test();
test.run();
}
public void run() {
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
Inner inner = new Inner();
engine.put("inner", inner);
try {
engine.eval("function run(inner){inner.foo(\"test\");} run(inner);");
} catch (ScriptException e) {
e.printStackTrace();
}
}
private class Inner {
public void foo(String msg) {
System.out.println(msg);
}
}
}在Java8下,此代码抛出以下异常:
javax.script.ScriptException: TypeError: kz.test.Test$Inner@117cd4b has no such function "foo" in <eval> at line number 1
at jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:564)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:548)https://stackoverflow.com/questions/22502630
复制相似问题