Windows ユーザー向けに JRuby で CLI アプリをつくる

## はじめに

### ※追記

この記事を書き終わった瞬間に [Warbler](https://github.com/jruby/warbler) という JRuby → jar をする gem を見つけました。
まだ試してないですが Warbler のほうがよさそうです。
Warbler については [[JRuby][Warbler]Rubyで書いたソースからJARを作成する ｜ Developers.IO](http://dev.classmethod.jp/etc/jruby_warbler_ruby_source_create_jar/) が詳しそうでした。

### 対象となる読者

* Windows ユーザーに CLI アプリを提供したいが CRuby をインストールしてもらえない。
* Ruby で作りたい！ ←ここ重要

### この記事を読んだ後できるようになること

* Java 環境があれば追加のインストールなく JRuby 製 CLI アプリが提供できる。
* Ruby を使うチャンスが増える！

### この記事を書いたときの環境

* Windows 7 (x64)
* jdk-8u144-windows-x64
* jruby-complete-9.1.12.0.jar

### ソースコード

この記事で説明しているソースコードは GitHub に置いてあります。

https://github.com/nkenbou/jruby-cli-for-win-boilerplate

これはボイラープレートとして作成したので素早く使える状態にできます。

## ファイル構成

最終的なファイル構成はこんな感じです。

```
./sample
  |-- hello.rb
  |-- hello.bat
  |-- Gemfile
  `-- vendor
       |-- jruby-complete-9.1.12.0.jar
       |-- jruby.bat
       |-- bundle.bat
       `-- gem_home
```

## jruby-complete-x.x.x.x.jar をダウンロードする

http://jruby.org/download から jruby-complete-x.x.x.x.jar をダウンロードして vendor に配置します。
これが JRuby の本体です。これを `java` コマンドに渡すことによって JRuby インタプリタとして動作します。

```bat
> jara -jar jruby-complete-9.1.12.0.jar --version
jruby 9.1.12.0 (2.3.3) 2017-06-15 33c6439 Java HotSpot(TM) 64-Bit Server VM 25.144-b01 on 1.8.0_144-b01 +jit [mswin32-x86_64]
```

毎回 `-jar ...` オプションをつけるのは面倒なので `jruby.bat` を作成して `jruby` コマンドっぽく実行できるようにします。

**jruby.bat**

```bat
@echo off

setlocal
set GEM_HOME=%~dp0gem_home
set GEM_PATH=%~dp0gem_home
java -jar %~dp0jruby-complete-9.1.12.0.jar %*
```

`GEM_HOME`、`GEM_PATH` は gem のインストール先を設定する環境変数です。正確には[マニュアル](https://docs.ruby-lang.org/ja/search/query:gem_home/#entry-3)を見てください。

ここでは、`vendoer/gem_home` にしています。

## Bundler で gem を管理する

やっぱり、Bundler を使って gem を管理したいですね。ということで、インストールします。

```bat
> vendor/jruby.bat -S gem install -i vendor/gem_home --no-document bundler
```

`bundle` コマンドを簡単にするために `bundle.bat` を作っておきます。

**bundle.bat**

```bat
@%~dp0jruby.bat -S %~dp0gem_home\bin\bundle %*
```

## Bundler で gem をインストールしてみます

今回はただの Hello, World! サンプルなので必要ないですが Gemfile に設定してインストールしてみます。

**Gemfile**

```rb
source "https://rubygems.org"
gem "nokogiri"
```

いつもは `--path vendor/bundle` を指定してインストールしているかもしれませんが、アプリ専用の `vendor/gem_home` にインストールされるため不要です (`--binstubs` オプションもいらないな)。

```bat
> vendor/bundle.bat install
```

`vendor/gem_home` に gem をまとめると、gem を 1つの jar にすることができて、配布が便利になります。

## 配布

gem を jar にします。

```bat
> jar cf gems.jar -C vendor\gem_home .
```

`jruby-complete-9.1.12.0.jar` と `gems.jar` を配布用のフォルダにコピーします。

そして、実行用 bat ファイルを作成します。

**hello.bat**

```bat
java -jar jruby-complete-9.1.12.0.jar -I./ -r gems.jar hello.rb
```

最終的な配布用のファイル構造です。

```
dist
  |-- hello.bat
  |-- hello.rb
  |-- jruby-complete-9.1.12.0.jar
  `-- gems.jar
```

## まとめ

CLI アプリであれば [ocra](https://github.com/larsch/ocra) が便利です。今回、この方法を調査したのは ocra では不都合な場面に出会ってしまったからでした。。。
ocra がダメな場合で、それでも Ruby で書きたい場合は当記事を参考にしてみてください。ただし、配布先に java 環境が必要です。

### 調査中に解決できなかったこと

rawr という gem を使って exe 化できるということなのでやってみましたが `print` 系のメソッドで標準出力が表示されませんでした。
ちなみに、ocra とは違って 1 ファイルだけの exe になるわけではなく、exe と jar が配布用のフォルダに出力されるようでした。

**Java プログラム** を exe 化する方法はあるみたいでしたが、そちらは exe 化したくなったときに調査してみます。

### 参考文献

* [Using Bundler with JRuby Complete](https://spin.atomicobject.com/2013/04/24/bundler-jruby-complete/)
* [JRubyで作ったスクリプトをwindowsユーザに提供する方法 - ハード屋のヨコ好き](http://d.hatena.ne.jp/shingo-zukunashi/20120707/1341682247)