はじめに
Java 上で JavaScript を実行するスクリプトエンジンは以下のように変遷してきました。
- Java 6 Rhino
- Java 8 Nashorn
- Java 11 Nashorn 非推奨化(https://openjdk.org/jeps/335)
- Java 15 Nashorn 削除(https://openjdk.org/jeps/372)
現在は、スクリプトエンジンとして GraalJS を使うのが選択肢になると思います。
以下のような依存を追加し、
implementation("org.graalvm.polyglot:polyglot:24.0.0") implementation("org.graalvm.polyglot:js:24.0.0")
Nashorn などと同じように以下のようにスクリプトエンジンを取得して使うことができます。
var engine = new ScriptEngineManager().getEngineByName("graal.js");
javet
Java 組み込みのスクリプトエンジンによるアプローチではなく、Java Native Interface (JNI) により直接V8を操作するライブラリが javet です。Java + V8 (JAVa + V + EighT)。
リポジトリは以下となります。
GraalJS と比較してパフォーマンスで優位なようです。
ここでは、javet の導入を簡単に紹介します。
javet の導入
Gradle でプロジェクトを作成します。
$ mkdir javet-example $ cd javet-example $ gradle init --type java-application --dsl kotlin --test-framework junit-jupiter --project-name javet-example --package javet.example
javet は JNI 経由で V8 を使うため、ライブラリはプラットフォーム毎に提供されています。
そのため、build.gradle.kts
には com.caoccao.javet
の依存をプラットフォームに応じて追加します。
import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform plugins { application } repositories { mavenCentral() } val os = DefaultNativePlatform.getCurrentOperatingSystem() val arch = DefaultNativePlatform.getCurrentArchitecture() val artifact = when { os.isMacOsX && arch.isArm64 -> "javet-macos" os.isMacOsX && arch.isAmd64 -> "javet-macos" os.isLinux && arch.isArm64 -> "javet-linux-arm64" os.isLinux && arch.isAmd64 -> "javet" os.isWindows && arch.isAmd64 -> "javet" else -> throw Error("Unsupported OS: $os, ARCH: $arch") } dependencies { implementation("com.caoccao.javet:${artifact}:3.1.0") } java { toolchain { languageVersion.set(JavaLanguageVersion.of(21)) } } application { mainClass.set("javet.example.App") }
V8Runtime の利用
利用は、V8Host.getNodeInstance()
からランタイムを取得して実行するだけです。
以下のようになります。
package javet.example; import com.caoccao.javet.interop.V8Host; import com.caoccao.javet.interop.V8Runtime; public class App { public static void main(String[] args) throws Exception { try (V8Runtime v8Runtime = V8Host.getNodeInstance().createV8Runtime()) { int ret = v8Runtime.getExecutor("1 + 2").executeInteger(); System.out.println("1 + 2 = " + ret); } } }
実行すれば、以下のような結果が得られます。
./gradlew run 1 + 2 = 3
その他詳細は以下のドキュメントを参照くてください。