从Rhino切换到Nashorn

Phi*_*ipp 28 rhino java-8 nashorn

我有一个Java 7项目,它使用Javascript来编写各种功能的脚本.到目前为止,我使用Rhino作为脚本引擎.我现在想转向Java 8,这也意味着我将取代Nashorn的Rhino.

Nashorn与Rhino的兼容性如何?我是否可以将其用作替代品,或者我是否可以预期我的某些脚本将不再工作并且需要移植到新引擎?是否有Nashorn不支持的Rhino常用功能?

Phi*_*ipp 25

一个问题是,Nashorn默认情况下不能再通过使用将整个Java包导入全局范围 importPackage(com.organization.project.package);

但是,有一个简单的解决方法:通过在脚本中添加此行,您可以启用Rhino的旧行为:

load("nashorn:mozilla_compat.js");
Run Code Online (Sandbox Code Playgroud)

我遇到的另一个问题是,在java和javascript之间传递数据时,某些类型转换的工作方式不同.例如,将Javascript数组传递给Java时到达的对象不能再转换为List,但可以转换为Map<String, Object>.作为一种解决方法,您可以使用Javascript代码将Javascript数组转换为Java ListJava.to(array, Java.type("java.util.List"))

  • 根据[本文](http://www.oracle.com/technetwork/articles/java/jf14-nashorn-2126515.html),"不鼓励使用mozilla_compat.js和importClass".使用`var scope = new JavaImporter(com.xy)`然后`scope.z`(其中z在包`com.xy`中).从JS数组到Java List的自动转换对我有用. (7认同)

jup*_*upi 10

要在JDK 8上使用importClass方法,我们需要添加以下命令:

load("nashorn:mozilla_compat.js");
Run Code Online (Sandbox Code Playgroud)

但是,此更改会影响JDK 7上的执行(JDK不支持load方法).

为了保持两个SDK的兼容性,我解决了添加try/catch子句的问题:

try{
    load("nashorn:mozilla_compat.js");
}catch(e){
}
Run Code Online (Sandbox Code Playgroud)


Rud*_*nos 9

当内部类被声明为私有时,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);
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

在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)
Run Code Online (Sandbox Code Playgroud)

  • 是的我知道.但这是某种不兼容性.恕我直言 (3认同)
  • 这完全取决于犀牛所缺乏的安全性. (3认同)