ScriptEngine実装
GraalVMでは、JavaScriptを実行するためのJSR-223準拠のjavax.script.ScriptEngine
実装が提供されています。この機能は、現在ScriptEngine
に基づく実装を簡単に移行できるようにするために、レガシーの理由から提供されていることに注意してください。設定の多くを直接制御し、GraalVMのよりきめ細かいセキュリティ設定のメリットを得ることができるように、org.graalvm.polyglot.Context
インタフェースを使用することをお薦めします。
Bindings
を介したオプションの設定
ScriptEngine
インタフェースには、オプションを設定するデフォルトの方法がありません。回避策として、GraalJSScriptEngine
では、Bindings
による一部のContext
オプションの設定がサポートされています。オプションは次のとおりです:
polyglot.js.allowHostAccess <boolean>
polyglot.js.allowNativeAccess <boolean>
polyglot.js.allowCreateThread <boolean>
polyglot.js.allowIO <boolean>
polyglot.js.allowHostClassLookup <boolean or Predicate<String>>
polyglot.js.allowHostClassLoading <boolean>
polyglot.js.allowAllAccess <boolean>
polyglot.js.nashorn-compat <boolean>
polyglot.js.ecmascript-version <String>
これらのオプションは、評価された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=2022 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", "2022"));
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
拡張子がサポートされています。