Ruby で処理した結果を DB に格納するまでの顛末 の続き

jar の配置が気にくわない

どうやら対象の jar は JRuby の lib ディレクトリに格納されている必要があるらしい。

Ruby で処理した結果を DB に格納するまでの顛末 - risou style

 って書いたけど、このツールは他のいくつかのツールと合わせて一つのツール群として提供する前提のもので、 JRuby の他に Jython も使っている都合上、ライブラリの jar はまとめておきたかった(同じ jar が2つもあるなんておかしいよね)。

 ということで、ちょっと調べてみたところ、「 jruby/lib に格納するか、 CLASSPATH に jar を追加すれば使える」とのことだったので、 CLASSPATH に jar を追加してみた。

 ところが、この方法だと例外がスローされているようでエラーが返ってくる。実際どう書いていたかと言うと、以下のように記述していた。

      java.lang.Class.forName('oracle.jdbc.driver.OracleDriver').newInstance
      con = java.sql.DriverManager.getConnection(DB_URL, DB_USER, DB_PASS)
      stmt = con.createStatement

 例外が発生するのは1行目。 Class#forName が怪しい。あるいは newInstance 。が、 JRuby の仕組みに詳しいわけでもないし、まずは正しく動くようにしたかったので原因を追求するのではなく、記述方法を変更。

include_class 'oracle.jdbc.driver.OracleDriver'

  def db_connect
    begin
      con = java.sql.DriverManager.getConnection(DB_URL, DB_USER, DB_PASS)
      stmt = con.createStatement
      ...
    end
  end

 include_class を用いることで newInstance する必要がなくなる。このやり方だと CLASSPATH に jar を追加しておけば正しく DB に接続してくれる。

CLASSPATH に jar を追加せずに同じことをやりたい

 環境ごとに CLASSPATH 設定してください、というのもユーザにとっては億劫だろうということで、 CLASSPATH に jar を追加せずに JRuby のプログラムで最初に処理する方式に変更。

require 'find'
cdir = Dir.pwd
Dir.chdir("#{libdir}")
Find.find(Dir.pwd) {|jar|
  if File.basename(jar) =~ /(.*\.jar)$/
    require jar
  end
}
Dir.chdir(cdir)

include_class 'oracle.jdbc.driver.OracleDriver'

 jar を格納しているディレクトリに移動し、 jar ファイルを走査して片っ端から require していく。それが終わったら、 include_class でクラスを include してあげれば、(正しく require できていれば) JRuby 上でクラスを使用することができる。