JSR-223経由でJython 2.5.2 を使う
*18日の記事に訂正記事を書いています。
http://d.hatena.ne.jp/cactusman/20110318/p1
Jython2.2.1なら問題なくできるのですが、最新バージョンだとうまくいかない、というのがメインのお話です。
そもそも、JSR-223 Scripting for the Java Platform はJava6に入った機能で、Javaからいろいろなスクリプト言語にアクセするための仕様です。
http://journal.mycom.co.jp/column/jsr/034/index.html
Rhino(js)は付属しているのそのまま使えるのですが、他の言語についてはプロジェクトサイトからjsr223-engines.zipまたは jsr223-engines.tar.gzをダウンロードする必要があります。
しかし、現時点ではjava.netからkenaiへの移行作業によってでしょうか、ダウンロードすることができません。
また、Mavenリポジトリもないため、ソースコードを直接ダウンロードし、ビルドするしかありません。
ビルドが終われば、付属しているJython2.2.1でなら問題なく実行できます。
しかし、Jython 2.5.2を呼ぼうとすると以下の例外が発生します。
Exception in thread "main" java.lang.VerifyError: class com.sun.script.jython.JythonScope overrides final method __findattr__.(Ljava/lang/String;)Lorg/python/core/PyObject; at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632) at java.lang.ClassLoader.defineClass(ClassLoader.java:616) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141) at java.net.URLClassLoader.defineClass(URLClassLoader.java:283) at java.net.URLClassLoader.access$000(URLClassLoader.java:58) at java.net.URLClassLoader$1.run(URLClassLoader.java:197) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:190) at java.lang.ClassLoader.loadClass(ClassLoader.java:307) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at java.lang.ClassLoader.loadClass(ClassLoader.java:248) at com.sun.script.jython.JythonScriptEngineFactory.getScriptEngine(JythonScriptEngineFactory.java:132) at javax.script.ScriptEngineManager.getEngineByName(ScriptEngineManager.java:225)
Jythonのバージョンアップに伴って、呼び出しているメソッドの引数が変わったりしているんでしょうか。
とりあえず、以下のように修正してみました。
Index: JythonScriptEngine.java =================================================================== --- JythonScriptEngine.java (リビジョン 236) +++ JythonScriptEngine.java (作業コピー) @@ -275,7 +275,7 @@ if (mode == null) { mode = "exec"; } - return __builtin__.compile(script, fileName, mode); + return (PyCode) Py.compile_flags(script, fileName, CompileMode.getMode(mode), Py.getCompilerFlags()); } catch (Exception exp) { throw new ScriptException(exp); } Index: JythonScope.java =================================================================== --- JythonScope.java (リビジョン 236) +++ JythonScope.java (作業コピー) @@ -70,7 +70,7 @@ } } - public PyObject __findattr__(String key) { + public PyObject __findattr_ex__(String key) { return __finditem__(key); } Index: JythonScriptEngine.java =================================================================== --- JythonScriptEngine.java (リビジョン 236) +++ JythonScriptEngine.java (作業コピー) @@ -275,7 +275,7 @@ if (mode == null) { mode = "exec"; } - return __builtin__.compile(script, fileName, mode); + return (PyCode) Py.compile_flags(script, fileName, CompileMode.getMode(mode), Py.getCompilerFlags()); } catch (Exception exp) { throw new ScriptException(exp); } Index: JythonScriptEngineFactory.java =================================================================== --- JythonScriptEngineFactory.java (リビジョン 236) +++ JythonScriptEngineFactory.java (作業コピー) @@ -38,7 +38,7 @@ } public String getEngineVersion() { - return "2.2.1"; + return "2.5.2"; } public List<String> getExtensions() { @@ -50,7 +50,7 @@ } public String getLanguageVersion() { - return "2.2.1"; + return "2.5.2"; } public String getMethodCallSyntax(String obj, String m, String... args) {
これでとりあえずビルドでき、Javaから実行できているのも確認しています。
ビルドする際は、libにあるjython.jarを2.5.2にしないとコンパイルエラーになります。
しかし、このあたりMavenリポジトリになんでないのかなと問い詰めたくなります・・・。
あと、各engineは各言語ごとにつけてほしいところです。