LoginSignup
50
38

[Java8] Java上でJavaScriptを動かす

Last updated at Posted at 2015-11-05

目的

  • 【追記】Java 8 で追加された以下の機能ですが、Java 11 で廃止されました。
  • Java6 あたりから、Java内にJavaScriptエンジン(Rhino)が追加されています。
  • Java8 ではJavaScriptエンジン(Nashorn)の性能が向上したという話なので、いまさらながら少し動かしてみました
  • でも性能測定とかはしません
  • メソッドの詳細な説明もしないです

概要

Java での JavaScript サポートは、ライブラリから扱える javax.script パッケージと、そのコマンドライン版があります。

実際には JavaScript 以外のスクリプト言語も対応が予定されているみたいですが、現時点では JavaScript のみが対応されているみたいです。

コマンドライン版

コマンドライン版は、Java6, Java7 では JDKの bin ディレクトリに jrunscript というコマンドがありました。これは Java8 でも残っているみたいです。

Java8 からは追加で JRE の bin ディレクトリに jjs というコマンドがあります。
開発環境(JDK)ではなく利用環境(JRE)だけでも使えるようになったのかな。

今回は触っていません。

javax.script パッケージ

JavaScript のソースの文字列から実行することができます(ファイルから読み込んで実行も可能)。

また、Java と JavaScript でデータのやり取りやメソッドの呼び出しなども可能です。

サンプルソース

とりあえず動かしてみました。例外処理は手を抜いています。

package test.javascript;

import java.util.Date;
import java.util.List;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;

/** Java と JavaScript の連携 */
public class JavaScriptTest {

	public static void main(String[] args) throws Exception {
		System.out.println("java.version: " + System.getProperty("java.version"));

        // 対応している ScriptEngine の情報を出力
		ScriptEngineManager manager = new ScriptEngineManager();
		List<ScriptEngineFactory> engineFactories = manager.getEngineFactories();
		for (ScriptEngineFactory factory : engineFactories) {
			System.out.println("Engine: " + factory.getEngineName()
					+ ", Version: " + factory.getEngineVersion());
			System.out.println("Language: " + factory.getLanguageName()
					+ ", Version: " + factory.getLanguageVersion());
			System.out.println("Extensions: " + factory.getExtensions());
			System.out.println("MimeTypes: " + factory.getMimeTypes());
			System.out.println("Names: " + factory.getNames());
			System.out.println();
		}
		ScriptEngine engine = manager.getEngineByName("JavaScript");

		// JavaScript の実行
		engine.eval("var message = 'Hello, I am JavaScript.'");
		engine.eval("print('#1: ' + message)");

		// Java のオブジェクトを JavaScript に渡してみる
		engine.put("message2", "Hello, I am Java8.");
		engine.put("today", new Date());
		engine.eval("print('#2: ' + message2 + ' now : ' + today.toString())");

		// JavaScript から Java のメソッドを使用
		engine.eval("var obj = Java.type('test.javascript.JavaScriptTest');"
				+ "print('#3: ' + obj.getMessage());");
		engine.eval("obj.printMessage('Good afternoon.');");

		// Java から JavaScript の値を取得
		engine.eval("var message3 = 'Good evening.';");
		Object message3 = engine.get("message3");
		System.out.println("#5: " + message3);

		// Java から JavaScript の関数を呼び出し
		if (engine instanceof Invocable) {
			Invocable invocable = (Invocable) engine;
			engine.eval("var func = function(arg) { print('#6: ' + arg);}");
			invocable.invokeFunction("func", "Good night.");
		}
	}

	/** メッセージを返す */
	public static String getMessage() {
		return "Good morning.";
	}

	/** メッセージを出力 */
	public static void printMessage(String message) {
		System.out.println("#4: " + message);
	}
}

動作結果はこんな感じ。

java.version: 1.8.0_65
Engine: Oracle Nashorn, Version: 1.8.0_65
Language: ECMAScript, Version: ECMA - 262 Edition 5.1
Extensions: [js]
MimeTypes: [application/javascript, application/ecmascript, text/javascript, text/ecmascript]
Names: [nashorn, Nashorn, js, JS, JavaScript, javascript, ECMAScript, ecmascript]

#1: Hello, I am JavaScript.
#2: Hello, I am Java8. now : Thu Nov 05 22:51:09 JST 2015
#3: Good morning.
#4: Good afternoon.
#5: Good evening.
#6: Good night.

落書き

  • Rhino の読みは「ライノー」で、英語で犀のこと
  • Nashorn のよみは「ナースホルン」でドイツ語で犀のこと
  • ネタ元はオライリーのJavaScript本なんでしょうね
50
38
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
50
38