web-dev-qa-db-ja.com

RhinoからNashornへの切り替え

Java 7プロジェクトがあり、さまざまな機能のスクリプト作成にJavascriptを多く使用しています。これまで、スクリプトエンジンとしてRhinoを使用していました。次にJava 8に移動したいと思います。これは、RhinoをNashornに置き換えることも意味します。

NashornはRhinoとどの程度互換性がありますか?ドロップイン置換として使用できますか、または一部のスクリプトが動作しなくなり、新しいエンジンに移植する必要があると期待できますか? NashornでサポートされていないRhinoの一般的に使用される機能はありますか?

28
Philipp

1つの問題は、NashornがデフォルトでimportPackage(com.organization.project.package);を使用してグローバルスコープにJavaパッケージ全体をインポートできない

ただし、簡単な回避策があります。この行をスクリプトに追加すると、Rhinoの古い動作を有効にできます。

_load("nashorn:mozilla_compat.js");
_

私が遭遇した別の問題は、Javaとjavascriptの間でデータを渡すときの特定のタイプ変換です。たとえば、Javascript配列をJavaはListにキャストできなくなりましたが、_Map<String, Object>_にキャストできます。回避策として、Javascript配列をJava = Java.to(array, Java.type("Java.util.List"))を使用してJavascriptコードにリストする

25
Philipp

JDK 8でimportClassメソッドを使用するには、次のコマンドを追加する必要があります。

load("nashorn:mozilla_compat.js");

ただし、この変更はJDK 7での実行に影響します(JDKはloadメソッドをサポートしていません)。

両方のSDKの互換性を維持するために、try/catch句を追加してこの問題を解決しました。

try{
    load("nashorn:mozilla_compat.js");
}catch(e){
}
10
jupi

Nashornは、内部クラスがprivateと宣言されている場合、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)
9

Rhinoには「in()」と呼ばれる関数に問題がないことに気付きました(ただし、「in」はJavaScriptの予約語です)。
Nashornはエラーを発生させます。

4
Houtman

Nashornはインスタンスの静的メソッドを呼び出すことができません! Rhinoはこれを行ったため、RhinoをJava 8にバックポートする必要がありました(以下に要約を示します: http://andreas.haufler.info/2015/04/using-rhino- with-Java-8.html

3
Andreas Haufler

Java8のNashornはASTをサポートしていません。したがって、RhinoのJavaメカニズムを使用してJSソースツリーを検査するコードASTコードがある場合は、 Nashornを使用するコード。

このAPIについて話している https://mozilla.github.io/rhino/javadoc/org/mozilla/javascript/ast/AstNode.html

Java9のNashornは、ASTをサポートしています。

0
NishM