2009.05.13

Programming

Java から Rails アプリのモデルを呼び出す (MacOSX Leopard)

Shindig Java 版から Rails アプリのモデルにアクセスする為に、Java から Ruby を呼び出すという技にチャレンジしてみました。

なんだか org.jruby.* を使う方法もあるようですが、とりあえず今回は Java 6 の Java Scripting とかいうのを使ってみました。

以下、手順をざっとおさらい。

JRuby のインストール

JSR233 Engines の Ruby エンジンは JRuby 1.1 系にしか対応していないらしいので、JRuby のバージョンを 1.3.0 から 1.1.6 に落とす。

これは jruby-bin-1.1.6.tar.gz をダウンロード&解凍して、JRUBY_HOME を置き換えるだけ。

JSR233 Engines のインストール

jsr223-engines.tar.gz をダウンロードして、適当な場所 (ここでは JSR233_ENGINE_HOME とする) に配置するだけ。

jruby.jar と jruby-engine.jar に CLASSPATH を通す
export CLASSPATH=$CLASSPATH:$JRUBY_HOME/lib/jruby.jar:$JSR233_ENGINES/jruby/build/jruby-engine.jar:.
Java Scripting Engine 利用時の JRuby の LOAD_PATH を修正

なぜか Java Scripting Engine と併用すると LOAD_PATHCLASSPATH で上書きされてしまうので、gem が呼べなくなってしまう。jruby.jar に gem を入れておくのもありだけど、今回はとりあえず LOAD_PATH を上書きしてやることにする。

$LOAD_PATH.unshift(
  ENV['JRUBY_HOME'] + '/lib/ruby/site_ruby/1.8',
  ENV['JRUBY_HOME'] + '/lib/ruby/site_ruby',
  ENV['JRUBY_HOME'] + '/lib/ruby/1.8',
  ENV['JRUBY_HOME'] + '/lib/ruby/1.8/java',
  'lib/ruby/1.8/java'
).uniq!
Rails アプリの environment.rb を Java コード内で require

あとはこんな感じのスクリプトで、Rails アプリ自体は読み込めた模様。

import java.io.*;
import javax.script.*;
public class JSmartfm {
  public static void main(String[] args) throws ScriptException, FileNotFoundException {
    ScriptEngine ruby = new ScriptEngineManager().getEngineByName("jruby");
    System.setProperty("jruby.home", "/usr/local/jruby");
    ruby.eval("require 'load_path_fixes'"); # 前述の $LOAD_PATH 上書きスクリプト
    ruby.eval("require 'RAILS_ROOT/config/environment'");
  }
}

まだ MySQL へのアクセスができないので、明日は MySQL-Ruby を JDBC に置き換えて試してみる予定。うまく行けば、毎回 Shindig のコンパイルしなくても良くなる、はず!