JDK6のScriptingでjythonを呼び出してみる
準備と利用
まず、scripting.dev.java.netから、jsr223-engines.zipをもらってきて展開する。(ドキュメントのリンクからアーカイブにたどり着ける)
この中にScriptEngineFactoryがいっぱいあるので、その中のjythonのjython-engine.jarをクラスパスに追加。
jython本体は含まれていないので、jython.jarは別途必要で、これもクラスパスに通しておく。
final ScriptEngineManager engMgr = new ScriptEngineManager(); for (final ScriptEngineFactory factory : engMgr.getEngineFactories()) { System.out.println("*engine=" + factory.getEngineName()); for (final String name : factory.getNames()) { System.out.println("name=" + name); } }
こんな感じで利用可能なスクリプトエンジンが増えているのが確認できる。
結果は、
*engine=Mozilla Rhino name=js name=rhino name=JavaScript name=javascript name=ECMAScript name=ecmascript *engine=jython name=jython name=python
jythonの場合は名前で索引するならば、「jython」「python」で取得できるようだ。
ためしに
final ScriptEngineManager engMgr = new ScriptEngineManager(); final ScriptEngine eng = engMgr.getEngineByName("jython"); eng.eval("def f(x):\n\treturn x + 1"); final Object ret = ((Invocable) eng).invokeFunction("f", 100); System.out.println(ret); System.out.println(ret.getClass());
とやって、結果は、
101 class java.lang.Integer
で、成功。
JavaScriptで定義したファンクションをjythonで使うことができるか試してみる。
final ScriptEngineManager engMgr = new ScriptEngineManager(); final ScriptEngine eng1 = engMgr.getEngineByName("js"); eng1.eval("function f(x) {return x+1;}"); final ScriptContext ctx = eng1.getContext(); final ScriptEngine eng2 = engMgr.getEngineByName("jython"); eng2.setContext(ctx); eng2.eval("print f(1);");
結果は、
Exception in thread "main" javax.script.ScriptException: Traceback (innermost last): File "<unknown>", line 1, in ? AttributeError: instance of 'sun.org.mozilla.javascript.internal.InterpretedFunction' has no attribute '__call__' at com.sun.script.jython.JythonScriptEngine.evalCode(JythonScriptEngine.java:292) at com.sun.script.jython.JythonScriptEngine.eval(JythonScriptEngine.java:170) at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:247)
で失敗。
うーん、__call__ねェ。
たしかに、pythonは、そんなものが必要かもねー。
一応、オブジェクトがあることは認識してるみたいだけど。
Javaからスクリプト言語のファンクションをうまい具合に呼び出せるのに、スクリプト間で呼び出せないのもヘンだな。
なにか方法がありそうな気がする。
とりあえず、今日はここまで。
以上、おわり。