まめ畑

ゆるゆると書いていきます

JRubyをAndroidで動かしてみた

JRubyをAndroidで動かしたい - まめ畑Android上でJRubyを動かそうとしてはまっていたと書きましたが、コメントでJRuby1.2.0だと動くと教えていただいたので試してみました。
結果は、動きました。
どうやら、1.3.0でバグが復活している模様です。
1.2.0で一応Androidで動くように対応した箇所がもとに戻っているという感じです。


JRubyAndroidで動かすように変換して転送する方法は上記のエントリを参照してください。
変換と転送が完了したら

# dalvikvm -Xss128k -classpath data/roboto.jar org.jruby.Main -e "puts 'JRuby on Android'"

と実行すると

dalvikvm -Xss128k -classpath data/roboto.jar org.jruby.Main -e "puts 'JRuby on Android'"
Error, could not compile; pass -d or -J-Djruby.jit.logging.verbose=true for more details
JRuby on Android

とエラーを吐きつつも実行されます。

これは、参考にしているサイトにも書かれていますがJRubyは逐次実行するインタプリタモードと実行前にコンパイルしてしまうPre-Compileの2つのmodeで動作しています。
しかし、ここでコンパイルされて出力されるのはJVM用のバイトコードなわけですが、AndroidではDalvikVM用のバイトコードしか実行できません。ここの部分でコンパイルエラーが出ています。
解決方法は、コンパイルしないで全てインタプリタモードで実行するようにしてしまえばいいです。
以下のように「-X-C」オプションをつけて実行するとインタプリタモードのみで実行されます。

# dalvikvm -Xss128k -classpath data/roboto.jar org.jruby.Main -X-C -e "puts 'JRuby on Android'"
dalvikvm -Xss128k -classpath data/roboto.jar org.jruby.Main -X-C -e "puts 'JRuby on Android'"
JRuby on Android

エラーが出なくなりました。


他にも

# dalvikvm -Xss128k -classpath data/roboto.jar org.jruby.Main -X-C -e "puts 1.class"
dalvikvm -Xss128k -classpath data/roboto.jar org.jruby.Main -X-C -e "puts 1.class"
Fixnum

# dalvikvm -Xss128k -classpath data/roboto.jar org.jruby.Main -X-C -e "1.upto(5){|i|puts i}"
dalvikvm -Xss128k -classpath data/roboto.jar org.jruby.Main -X-C -e "1.upto(5){|i|puts i}"
1
2
3
4
5

は当然の事ながら

# dalvikvm -Xss128k -classpath data/roboto.jar org.jruby.Main -X-C -e "require 'java'; puts java.lang.System.get_property('java.vendor')"
dalvikvm -Xss128k -classpath data/roboto.jar org.jruby.Main -X-C -e "require 'java'; puts java.lang.System.get_property('java.vendor')"
The Android Project

の様にJavaのメソッドも使えます。


まだnativeの機能を使うものなど動かないライブラリも多いですが対応が進んでいるようです。
しかし、なぜ1.3.0で以前の修正が元に戻ったのでしょうか。