seraphyの日記

日記というよりは過去を振り返るときのための単なる備忘録

JDK6でJavaScriptで定義したFunctionをJavaから呼び出す。

JDK6のRCが出たので、BETA2を消して入れなおす。
ドキュメントもダウンロードしたので、改めてみると、以前見過ごしていたことに気がつく。

前回の日記で、Invocableなどという、それらしいインタフェースはあるが、スクリプト定義のファンクションをJAVA側から呼び出す方法がないのではないか、とつぶやいたが、誤りだったようだ。
JAVADOCに、

public interface Invocable

The optional interface implemented by ScriptEngines whose methods allow the invocation of procedures in scripts that have previously been executed.

と書いてあって、Invocableは、スクリプトエンジンに対するオプションのインタフェースなのであった。
そして、JDK6のRhinoには、このインタフェースが実装されていることが判明。
そこで、以下のような実験をしてみた。

try {
    final ScriptEngine eng2 = engMgr.getEngineByName("js");
    eng2.setContext(ctx);
    ((Invocable) eng2).invokeFunction("f");
}
catch (final NoSuchMethodException e) {
    e.printStackTrace();
}
catch (final ScriptException e) {
    e.printStackTrace();
}

コンテキストctxは、予めJavaScriptをevalして関数fを定義させたものである。
このコンテキストctxをスクリプトエンジンに渡して、Invocableインタフェースを経由してメソッド呼び出してみた。
正しく関数fが呼び出されたことを確認。
(ちなみに、存在しない関数名を指定すると、NoSuchMethodException例外が発生することも確認。)

このinvokeFunctionメソッドには、メソッド名のほかに、可変長引数を指定することができ、それを引数として渡すこともできる。
よって、JDK6でスクリプト定義のファンクションを直接呼び出す方法がないのではないか、という懸念は杞憂であった。

以上、おわり。