JDK 1.8 から Java 内で JavaScript を実行する方法

Java 1.8 では、組み込みの javax.script パッケージを使用して、Java アプリケーション内で JavaScript コードを実行できます。以下に、実際の利用シーンに基づいた複数の例を示します。

例 1: 変数の保存と取得


ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("javascript");

// コンテキストに変数を設定
engine.put("msg", "just a test");</p>

<p>// JavaScript コードを定義して実行
String jsCode = "msg += '!!!'; var user = {name:'tom', age:23, hobbies:['football','basketball']};";
engine.eval(jsCode);

// Java 側で値を取得
String msg = (String) engine.get("msg");
System.out.println(msg);  // 出力: just a test!!!

Object user = engine.get("user");
// Gson を使って Object を Map に変換
Gson gson = new Gson();
Map<String, Object> userMap = gson.fromJson(gson.toJson(user), Map.class);
System.out.println(userMap);

例 2: JavaScript 関数の呼び出し


ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("javascript");</p>

<p>// 関数を定義
engine.eval("function add(a, b) { return a + b; }");

// Invocable インターフェースを使って関数を呼び出し
Invocable invocable = (Invocable) engine;
Object result = invocable.invokeFunction("add", 10, 5);
System.out.println(result);  // 出力: 15

例 3: Runnable として JavaScript 関数を実行


ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("javascript");</p>

<p>// 実行する関数を定義
engine.eval("function run() { print('Hello from JS thread'); }");

Invocable invocable = (Invocable) engine;
// Runnable インターフェースとして関数を取得
Runnable runner = invocable.getInterface(Runnable.class);
Thread t = new Thread(runner);
t.start();
t.join();

例 4: JavaScript 内で Java クラスを利用

注意: JDK 1.8 では importPackage は使えません。代わりに完全修飾名で参照します。


ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("javascript");</p>

<p>String jsCode = "var list = java.util.Arrays.asList(['X', 'Y', 'Z']);";
engine.eval(jsCode);</p>

<p>List<String> list = (List<String>) engine.get("list");
for (String value : list) {
    System.out.println(value);
}

例 5: 外部 JS ファイルの読み込みと実行


ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("javascript");</p>

<p>FileReader reader = new FileReader("C:/scripts/expression.js");
engine.eval(reader);

if (engine instanceof Invocable) {
    Invocable invocable = (Invocable) engine;
    // JS ファイルで定義された merge 関数を呼び出す
    Double result = (Double) invocable.invokeFunction("merge", 2, 3);
    System.out.println("merge result: " + result);
}
reader.close();

付録: JavaScript オブジェクトを Java の型に変換するユーティリティ


import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public static <T> T convertToType(Object obj, Class<T> targetClass) {
    Gson gson = new Gson();
    return gson.fromJson(gson.toJson(obj), targetClass);
}

詳細については、公式ドキュメントを参照してください: ScriptEngine (Java SE 7)

タグ: Java javascript JDK1.8 ScriptEngine Nashorn

6月20日 21:19 投稿