[JRuby][Warbler]Rubyで書いたソースからJARを作成する – (2)定義ファイルの参照と、その他のポイント

2015.09.24

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

JRubyで書いたソースからJARを作成する方法について、以前[JRuby][Warbler]Rubyで書いたソースからJARを作成するという記事を書きました。先日、実案件を想定して改めてやってみたところ、以前には分からなかったポイントをいくつか発見しました。そこで以前の記事を補完する形で、それらについて書きたいと思います。

前提条件

JRubyで書いたソースからJARを作成する基本的な方法については、以前の記事を参考にしてください。プロジェクトのフォルダ構成などに注意が必要です。

今回は以下の実行環境にて開発を行いました。(恐らくは前回と同様の環境でも動くはずです。)

  • jruby 9.0.0.0
  • java version "1.8.0_25"

またJARの作成には、前回と同様にWarblerを使います。

ポイント

1.定義ファイルの参照について

実案件で使用する場合、定義ファイルなど外部ファイルを参照することがあるかと思います。この場合、開発時のパスとJARにした状態でのパスに注意する必要があります。

例えば、以下のような構成として、app/main.rbから定義ファイル(settings.yml)を参照するとします。

$
├── Gemfile
├── Gemfile.lock
├── settings.yml       ・・・定義ファイル
├── WarblerSample.jar ・・・JAR作成時に出力される
├── app                ・・・メインとなる処理を記述する
│   ├── main.rb        ・・・定義ファイルを参照するロジック
├── bin
│   └── init.rb        ・・・起動時に実行する処理を記述する

setting.ymlの参照先として以下の様なソースを書くと、「$ jruby init.rb」のようにRubyファイルを起動した場合は動くのですが、JARでの実行時に参照できません。

File.expand_path("../../settings.yml", __FILE__)

理由は、「__FILE__」はJARでの実行時にはJAR内のファイルパスを指すため、OS内のパスとはならない為です。定義ファイルはJAR内には無いため、定義ファイルを読み取れないことになります。

解決法としては、「Dir.pwd」でOS内のパスを取得するようにしました。(ベタな方法ですが)以下のコードをinit.rbに記述し、グローバル変数にアプリのルートパスを格納するようにしました。

@@JAR_PATH = Dir.pwd.gsub(/\/bin$/, "")

「$ jruby init.rb」のようにinit.rbを起動した際にはDir.pwdは「ルートパス/bin」を返します。このためgsub()で末尾の「/bin」を取り除き、ルートパスを「@@JAR_PATH」に格納します。JARを起動した際には、Dir.pwdはJARのパス(今回はルートパスと同じとなる)を返します。よって、ルートパスが「@@JAR_PATH」に格納されることになります。定義ファイル自体にパスは、以下のようになります。

File.join(@@JAR_PATH, "settings.yml")

2.$LOAD_PATHへの追加

これはRubyの$LOAD_PATHにカレントパスが含まれない問題とも絡んでいます。「require」で他のファイルを参照するためと、JARでの実行時にgemを参照するため、$LOAD_PATHにカレントパスとgemのパスを追加します。init.rbに以下を記述します。

$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../"))

Dir.glob(File.expand_path('vendor/bundle/jruby/*/gems/*/lib')).each{|path|
  $LOAD_PATH << path if !$LOAD_PATH.include?(path)
}

3.開発時とJARでのエントリーポイントについて

アプリの作りにもよりますが、現時点で私は「init.rb」をエントリーポイントとすることが分かりやすいように思えます。なので開発時には「init.rb」をjrubyコマンドで叩くことになります。

参考サイト

jruby/warbler
Ruby 1.9.2から$LOAD_PATHにカレントディレクトリが含まれなくなった