ruby iknow gemをJRubyでも使えるようにする

iKnow!のAPIプログラムコンテスト用アプリ環境構築を前回から始めたんですが、早速JRubyにnov-iknowモジュールをインストールするところでコケてしまいました。原因は、このモジュールが利用しているjsonライブラリがCのネイティブコードを使っていたためです。とりあえず、これを回避できればインストールできそうです。

まず、gemでほかにjsonパッケージがないか調べてみます。

$ jruby -S gem search -r json

*** REMOTE GEMS ***

fjson (0.1.2)
json (1.1.3)
json-jruby (1.1.2)
json_pure (1.1.3)
jsonpath (0.0.1)
jsont (0.1.2)
Orbjson (0.0.4)
proc2json (0.0.1)
ruby-json (1.1.2)

json-jrubyというのがいかにも、、ですね。バージョンも近いですし。RubyForgeにホストされているようなので、見てみます。

JSON-JRuby is a port of Florian Frank's native json library to JRuby. It aims to be a perfect drop-in replacement for json_pure.

http://rubyforge.org/projects/json-jruby/

ということは、gemでjsonの代わりにこのパッケージに依存するようにすれば、インストールできそうです。githubにあるnov-inowのgemspecの一部に依存の記述がありますね。

    s.add_dependency(%q<rails>, [">= 2.1.0"])
    s.add_dependency(%q<json>, [">= 0"])
    s.add_dependency(%q<oauth>, [">= 0.2.4"])

この、jsonの部分をjson-jrubyとすればいけるんじゃないですか?では、さっそく・・・
ほんとはgitで取得してくるのが本当でしょうけど、まだgit環境を構築していないのでgithubのwebからダウンロードしてきます。

GitHub - nov/iknow: moved to smartfm

の、「download」リンクからtar形式でローカルにダウンロードしてきて、展開します。

$ wget http://github.com/nov/iknow/tarball/master
$ tar xvfz nov-iknow-*.tar.gz

上記のjsonのところ3箇所を、json-jrubyに置換します。そして、このgemspecファイルでbuild, installしてみます。

$ jruby -S gem build iknow.gemspec
  Successfully built RubyGem
  Name: iknow
  Version: 0.0.4
  File: iknow-0.0.4.gem
$ sudo $JRUBY_HOME/bin/jruby -S gem install iknow-0.0.4.gem
Successfully installed json-jruby-1.1.2-universal-java-1.6
Successfully installed ruby-hmac-0.3.2
Successfully installed oauth-0.2.7
Successfully installed iknow-0.0.4
4 gems installed
Installing ri documentation for ruby-hmac-0.3.2...
Installing ri documentation for oauth-0.2.7...
Installing ri documentation for iknow-0.0.4...
Installing RDoc documentation for ruby-hmac-0.3.2...
Installing RDoc documentation for oauth-0.2.7...
Installing RDoc documentation for iknow-0.0.4... 

おおおおお、インストールできました!!
さっそくサンプルを動かしてみましょう。同梱されていたサンプル(examples/pure_ruby.rb)のまねをjirbでしてみます。

$ jruby -S irb
irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> require 'iknow'
JRuby limited openssl loaded. gem install jruby-openssl for full support.
http://wiki.jruby.org/wiki/JRuby_Builtin_OpenSSL
=> true
irb(main):003:0>
irb(main):004:0* Iknow::Config.init do |conf|
irb(main):005:1*   conf.api_key               = '***'
irb(main):006:1>   conf.oauth_consumer_key    = ''
irb(main):007:1>   conf.oauth_consumer_secret = ''
irb(main):008:1> end
=> #<Iknow::Config:0xefeff8 @oauth_consumer_key="", @api_protocol="http", @source="iknow", @application_name="A rubygem for iKnow! API", @api_key="***", @protocol="http", @oauth_consumer_secret="", @user_agent="default", @api_host="api.iknow.co.jp", @application_version="0.0.4", @host="www.iknow.co.jp", @api_port=80, @port=80, @application_url="http://github.com/nov/iknow_oauth_generator">
irb(main):009:0> @matched_lists = Iknow::List.matching("イタリア語であいさつ")
=> [#<Iknow::List:0x7bd46a @dictation=#<Iknow::List::Application:0x1b6a053 @lang="ja", @list_id=31509, @application="dictation">, @description="Ciao Ciao\r\nStudiamo Italiano insieme (snip)

つながりました!これで、JRubyでもiknow gem使えることがわかりました!!

あまりJRuby+iknow gemということをやりたい人は少数かもしれないですが、もしほかにいたら本家にも取り込んで簡単にJRubyでも使えるようにしたいですね。