ScriptEngine実装

GraalVMでは、JavaScriptを実行するためのJSR-223準拠のjavax.script.ScriptEngine実装が提供されています。この機能は、現在ScriptEngineに基づく実装を簡単に移行できるようにするために、レガシーの理由から提供されていることに注意してください。設定の多くを直接制御し、GraalVMのよりきめ細かいセキュリティ設定のメリットを得ることができるように、org.graalvm.polyglot.Contextインタフェースを使用することをお薦めします。

Bindingsを介したオプションの設定

ScriptEngineインタフェースには、オプションを設定するデフォルトの方法がありません。回避策として、GraalJSScriptEngineでは、Bindingsによる一部のContextオプションの設定がサポートされています。オプションは次のとおりです:

これらのオプションは、評価されたJavaScriptコードに適用されるサンドボックス化ルールを制御し、アプリケーションがNashorn互換性モード(--js.nashorn-compat=true)で起動されていないかぎり、デフォルトではfalseに設定されます。

ScriptEngineを使用すると、暗黙的に試験段階のオプションが許可されることに注意してください。これは、Bindingsを介して渡すことができるオプションを網羅したリストであり、GraalVM JavaScriptに追加オプションを渡す必要がある場合は、次に示すようにContextを手動で作成する必要があります。

Bindingsを介してオプションを設定するには、エンジンのスクリプト・コンテキストが初期化されるに、Bindings.put(<option name>, true)を使用します。Bindings#get(String)のコールでもコンテキストの初期化につながる場合があることに注意してください。次のコードは、Bindingsを介してpolyglot.js.allowHostAccessを有効にする方法を示しています:

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'));"); // it will not work without allowHostAccess and allowHostClassLookup

この例は、ユーザーがbindings.put("polyglot.js.allowHostAccess", true);をコールする前に、たとえばengine.eval("var x = 1;")をコールした場合は機能しませんが、これはevalをコールするとコンテキストが強制的に初期化されるためです。

システム・プロパティを介したオプションの設定

JavaScriptエンジンに対するオプションは、先頭にpolyglot.を付加することで、JVMを起動する前にシステム・プロパティを介して設定できます:

java -Dpolyglot.js.ecmascript-version=2021 MyApplication

または、JavaScriptエンジンに対するオプションは、ScriptEngineを作成する前にJava内からプログラムで設定できます。ただし、これはJavaScriptエンジンに渡されるオプション(js.ecmascriptなど)にのみ機能し、Bindingsを介して設定できる前述の6つのオプションには機能しません。また、これらのシステム・プロパティは、同時に実行されるすべてのScriptEngineによって共有されることに注意してください。

柔軟性を高めるためのContextの手動作成

Contextのオプションは、Context.Builderのインスタンスを介してGraalJSScriptEngineに直接渡すこともできます:

ScriptEngine engine = GraalJSScriptEngine.create(null,
        Context.newBuilder("js")
        .allowHostAccess(HostAccess.ALL)
        .allowHostClassLookup(s -> true)
        .option("js.ecmascript-version", "2021"));
engine.put("javaObj", new Object());
engine.eval("(javaObj instanceof Java.type('java.lang.Object'));");

これにより、GraalVM JavaScriptで使用可能なすべてのオプションを設定できます。これには、GraalJSScriptEngineクラスやContextクラスなど、GraalVM JavaScriptに対する強い依存性が伴います。

サポートされるファイル拡張子

javax.script.ScriptEngineのGraalVM JavaScript実装では、JavaScriptソース・ファイルのjsファイル拡張子、およびESモジュールのmjs拡張子がサポートされています。