JRuby上で動かしてみました
GW 明けの JavaOne では、JRuby 1.0 のリリースが期待されています。
JRuby 上で AP4R を動かせれば、枯れた VM 上で動くという安心感もあるし、既存の Javaアプリとの連携もちょっと楽になるかもなぁと妄想しつつ、、、
今回は Ruby本家の処理系で動く Rails アプリと JRuby 上で動く AP4R を連携させてみました。
- 準備
まずは、JRuby 本体をインストールします。
% curl -o http://dist.codehaus.org/jruby/jruby-bin-0.9.8.tar.gz % tar xvf jruby-bin-0.9.8.tar.gz % mv jruby-bin-0.9.8 jruby-0.9.8 % mv jruby-0.9.8 /usr/local
環境変数を設定しておきます。
% export JRUBY_HOME=/usr/local/jruby-0.9.8 % export PATH=$PATH:$JRUBY_HOME/bin
% curl -O http://files.rubyforge.vm.bytemarkco.uk/rubygems-0.9.2.tgz % tar xvfz rubygems-0.9.2.tgz % cd rubygems-0.9.2.tgz % jruby setup.rb
- AP4R のセットアップ
いつもと同じように、gem からインストールします。
% sudo /usr/local/jruby-bin-0.9.8/lib/ruby/gem install ap4r -y
AP4R の作業フォルダをつくります。
% cd ~/work/temp % /usr/local/jruby-0.9.8/bin/ap4r_setup my_ap4r make application root directory [/Users/kiwamu/work/temp/my_ap4r] ... make directories for AP4R [config, log, script, tmp] ... copy files from /usr/local/jruby-0.9.8/lib/ruby/gems/1.8/gems/ap4r-0.3.0/config to /Users/kiwamu/work/temp/my_ap4r/config ... copy files from /usr/local/jruby-0.9.8/lib/ruby/gems/1.8/gems/ap4r-0.3.0/script to /Users/kiwamu/work/temp/my_ap4r/script ... [/Users/kiwamu/work/temp/my_ap4r] has successfully set up!
で、起動します。ここまで非常に順調でした♪
% cd my_ap4r % jruby script/start -c config/queues_disk.cfg Loaded queues configuration from: /Users/kiwamu/work/temp/my_ap4r/config/queues_disk.cfg Using message store: disk Error in starting queue-manager undefined method `sysseek' for #<File:/Users/kiwamu/work/temp/my_ap4r/queues/master.idx> /usr/local/jruby-0.9.8/lib/ruby/gems/1.8/gems/reliable-msg-1.1.0/lib/reliable-msg/message-store.rb:356:in `method_missing' /usr/local/jruby-0.9.8/lib/ruby/gems/1.8/gems/reliable-msg-1.1.0/lib/reliable-msg/message-store.rb:356:in `update' /usr/local/jruby-0.9.8/lib/ruby/gems/1.8/gems/reliable-msg-1.1.0/lib/reliable-msg/message-store.rb:278:in `synchronize' /usr/local/jruby-0.9.8/lib/ruby/gems/1.8/gems/reliable-msg-1.1.0/lib/reliable-msg/message-store.rb:369:in `update' /usr/local/jruby-0.9.8/lib/ruby/gems/1.8/gems/reliable-msg-1.1.0/lib/reliable-msg/message-store.rb:278:in `activate' /usr/local/jruby-0.9.8/lib/ruby/gems/1.8/gems/reliable-msg-1.1.0/lib/reliable-msg/queue-manager.rb:233:in `start' /usr/local/jruby-0.9.8/lib/ruby/gems/1.8/gems/ap4r-0.3.0/lib/ap4r/script/../../ap4r/queue_manager_ext.rb:59:in `synchronize' /usr/local/jruby-0.9.8/lib/ruby/gems/1.8/gems/reliable-msg-1.1.0/lib/reliable-msg/queue-manager.rb:269:in `start' /usr/local/jruby-0.9.8/lib/ruby/gems/1.8/gems/ap4r-0.3.0/lib/ap4r/script/../../ap4r/queue_manager_ext.rb:59:in `start' /usr/local/jruby-0.9.8/lib/ruby/gems/1.8/gems/reliable-msg-1.1.0/lib/reliable-msg/cli.rb:109:in `synchronize' /usr/local/jruby-0.9.8/lib/ruby/gems/1.8/gems/ap4r-0.3.0/lib/ap4r/script/../../ap4r/queue_manager_ext.rb:63:in `start' /usr/local/jruby-0.9.8/lib/ruby/gems/1.8/gems/reliable-msg-1.1.0/lib/reliable-msg/cli.rb:109:in `run' /usr/local/jruby-0.9.8/lib/ruby/gems/1.8/gems/ap4r-0.3.0/lib/ap4r/script/../../ap4r/script/queue_manager_control.rb:23:in `run_rm_client' /usr/local/jruby-0.9.8/lib/ruby/gems/1.8/gems/ap4r-0.3.0/lib/ap4r/script/../../ap4r/script/queue_manager_control.rb:13:in `start' script/start:5
あ... orz
- 原因追及
エラー文言をみると、どうも IO#sysseek なんていうメソッドはないと怒られているっぽい。よくよく見てみると、JRuby では、sysread や syswrite はあるのに sysseek の実装がない...
% cat hoge >> hoge % jirb irb(main):001:0> f=File.new("hoge") => #<File:hoge> irb(main):002:0> f.sysseek(1, IO::SEEK_SET) NoMethodError: undefined method `sysseek' for #<File:hoge> from (irb):1:in `method_missing' from (irb):1:in `binding' irb(main):003:0> f.methods.any? {|m| m == "sysseek"} => false irb(main):004:0> f.methods.any? {|m| m == "seek"} => true
IO#seek はあるので、違いを見てみると戻り値だけらしい。
- ios.sysseek(offset, whence=SEEK_SET) => integer
Seeks to a given offset in the stream according to the value of whence (see IO#seek for values of whence). Returns the new offset into the file.
f = File.new("testfile")
f.sysseek(-13, IO::SEEK_END) #=> 53
f.sysread(10) #=> "And so on."
- ios.seek(amount, whence=SEEK_SET) → 0
Seeks to a given offset anInteger in the stream according to the value of whence:
IO#sysseek を呼び出しているのは reliable-msg/message-store.rb ですが、とくに戻り値を利用しているわけではなかったので、このメソッドをすべて IO::seek に置き換えてみます。
あ、あと忘れずに gems 以下の uuid-x.x.x の permission も変えておきます。
% sudo chmod 757 /usr/local/jruby-0.9.8/lib/ruby/gems/1.8/gems/uuid-1.0.3
- リトライ
気を取り直して、AP4R を再び起動してみます。
% sudo chmod 757 /usr/local/jruby-0.9.8/lib/ruby/gems/1.8/gems/uuid-1.0.3 % Rm -rf queues/master.idx % jruby script/start -c config/queues_disk.cfg Loaded queues configuration from: /Users/kiwamu/work/temp/my_ap4r/config/queues_disk.cfg Using message store: disk Accepting requests at: druby://localhost:6438 about to start dispatchers with config --- - threads: 1 targets: queue.* dispatch targets are : queue.*; start dispatcher: targets= #<ReliableMsg::MultiQueue:0xc89df9> (index 0) queue manager has forked dispatchers
今度はうまくいったようです♪
- サンプルアプリを実行
こちらは Ruby でふつーに実行しておきます。
% cd ~/work/temp % curl -O http://rubyforge-files.ruby-forum.com/ap4r/HelloWorld-0.3.0.tar.gz % tar xvfz HelloWorld-0.3.0.tar.gz % cd HelloWorld % ruby script/server
ブラウザから以下の URL をたたいてみてください。
ちゃんと動いたでしょうか? JRuby、素晴らしいですね〜♪
JRuby上で動かした Railsアプリとの連携はまだちょっとうまくいかなかったので、そこらへんはまた後日... (^^;