Java 6 から導入されたスクリプトAPIを利用する

最近,業務で Java を頻繁に使うようになりました(私は社会人1年目のぺえぺえです).
いろいろ調べていたら,Java 6 から Script API が導入されたことを知りました.へぇ〜.

ScriptEngineを使う

Oracle Technology Network for Java Developers
Oracle Technology Network for Java Developers
上記ページで説明されています.

スクリプトの実行時に使用する ClassLoader を変更したい

ScriptEngine の場合,ClassLoader は

java.lang.Thread.currentThread().getContextClassLoader();

が使用されるようです.


これを変更したいときは,Rhino を組み込む手順と同じことをすれば可能になります.
Rhino 組み込み


具体的には,

Context context = Context.enter();

// ClassLoader を変更
context.setApplicationClassLoader(/* ここにクラスローダをセット */);

とすることで変更できます.
これで,JavaScript から,

var hoge = JavaImporter(Packages.org.example.hoge);
var h = new hoge.Hoge();

のように,設定したクラスローダ経由で Java クラスが使えるようになります.


JDK1.6.0_03 に組み込まれた Rhino を利用する場合は,

sun.org.mozilla.javascript.internal

以下のクラスを使用することになります.


Rhino の jar を直接利用する場合は,

org.mozilla.javascript

を使用します.


だいたいこんな感じで使えばよいのでしょうか.
API の詳しい使い方は,Javadocを参照)

Context context = Context.enter();
try {
	ScriptableObject root = context.initStandardObjects();
	// JavaScript で ImportPackage を使いたい場合は,上記コードの代わりに
	// ScriptableObject root = new ImporterTopLevel(context);
	// とする.

	// 1: スクリプト,2: スクリプトが記述されたファイル名,3: 開始行番号,4: Securityを気にしない場合はnull
	// ↑by Rhino 1.6r7 のコードより
	Script compiledScript = context.compileString(script, "<Script String1>", 1, null);

	// 指定された context と root (Scope) で,スクリプトを実行
	// ↓実行結果もとれるよ
	compiledScript.exec(context, root);

	Object ret = null;
	// 上のscriptで,例えば "function main()" を定義していた場合,以下のようにして実行する
	ret = context.evaluateString(root, "main();", "<Script String2>", 1, null);
	
} finally {
	Context.exit();
}

...あってるかな?

その他

スクリプト実行後の結果を Java から利用するときには,

Object ret = context.evaluateString( ... );
if(ret instanceof NativeJavaObject) {
	ret = ((NativeJavaObject) ret).unwrap();
}

こんな風に取得することも可能です.
(標準はこっち→ Rhino 組み込み