Ruby Application を Windows, Mac でも簡単に使用できるように配布する

皆さんがせっかく作った Ruby Application, どうせなら色んな人に使ってもらいたいと思いませんか？
とはいえ， Ruby User には `gem install hoge` してくださいと言えば伝わるものの，非 programmer の user にはそうはいきません．一般 user からすれば， `.exe` 形式や `.app` 形式でないとちょっと敷居が高いと思います．
それなら， [Rawr](https://github.com/rawr/rawr) を使って， Ruby Application を `.exe` 化， `.app` 化しましょう！

**note**: Web 上に `Rawr` に関する記事はいくつか見つかりましたが， gem library を require するような Application をパッケージ化する方法については，正しく動作するようなものが見つからなかったため，記事にまとめることにしました．

# Requirement

- JRuby >= 1.7.0
- javac
- Rake

`JRuby` が必要となるので，環境を整えておきましょう．
今回は， `rbenv` を使用している前提で進めていきます．

## JRuby の導入

```bash
$ rbenv --version
# rbenv 0.4.0-98-g13a474c
$ rbenv install jruby-1.7.12
$ rbenv rehash
```

## Rawr の 導入

```bash
$ jruby -S gem install rawr --source http://gems.neurogami.com
```

source を指定しないといけないので注意です．

# HelloWorld Project の作成

では，まずは簡単な Subject から進めて， `Rawr` が動作することを確認しましょう．

## Rawr Project のセットアップ

```bash
$ mkdir hello_world
$ cd hello_world
$ rbenv local jruby-1.7.12
$ jruby -S rawr install
$ ls
# Rakefile  build_configuration.rb  lib/  src/
```

これで， Project の skeleton が完成しました．
まず，今回の実行プログラムは `hello_world.rb` なので，これを `Rawr` に知らせます

```bash
$ vim build_configuration.rb
```

次のように編集します．

https://gist.github.com/huyu398/1660d0ead7189d5a5be3/374308d1829e9844edcb548a882079d1e8b1e23f

これで， `src` directory に `hello_world.rb` を書けば `Rawr` が Packaging してくれます！

## HelloWorld Program の作成と確認

```bash
$ vim src/hello_world.rb
$ jruby src/hello_world.rb
# Hello world!
```

https://gist.github.com/huyu398/1660d0ead7189d5a5be3/5f25aac4b7bbcbb4b09821bd52f1a00d998de81e

## Packaging

```bash
$ jruby -S rake rawr:jar
$ java -jar package/jar/rawr_test.jar
# Add 'src/' to $:
# Hello world!
```

この時点で， `package/jar` を配布すれば， java が実行できる環境であれば HelloWorld Program が実行できます．

`.exe` 化， `.app` 化は次のコマンドで実行できます．
**note**: 実行未確認

```bash
$ jruby -S rake rawr:bundle:exe
$ jruby -S rake rawr:bundle:app
```

これで， `package/window`, `package/osx` directory を配布すれば， HelloWorld Program が各 OS で簡単に実行できます．

# 依存 Gem のある Project の作成

次に， `require 'hoge'` といった， 依存 Gem のあるような Program を作成してみます．
今回は，例として [dydx](http://qiita.com/gogotanaka/items/834eca2c1774a73b251c) を使用します．

## Configuration と Program の変更

```bash
$ vim build_configuration.rb
$ mv src/hello_world.rb src/dydx_test.rb
$ vim src/dydx_test.rb
$ jruby -S gem install dydx
$ jruby src/dydx_test.rb
# ( 2 + ( 3 * a ) )
```

https://gist.github.com/huyu398/1660d0ead7189d5a5be3/77b2898d21c1bbd484408b90b83a93108ae6b126

## 依存 Gem の読み込み

`Rawr` は残念ながら `Gemfile` からの依存 Gem の解決や，それに準ずることは行ってくれません．
手動で library となっている ruby application を知らせる必要があります．

```bash
$ jruby -S gem install -i lib/ruby dydx --no-rdoc --no-ri
$ vim build_configuration.rb
```

https://gist.github.com/huyu398/1660d0ead7189d5a5be3/4d8842eb705344abdc6e08cae1d5dcc7ddc179db

あとは，先ほどと同様に Packaging します．

```bash
$ jruby -S rake rawr:clean
$ jruby -S rake rawr:jar
$ java -jar package/jar/rawr_test.jar
# Add 'src/' to $:
# Add 'lib/ruby/gems/dydx-0.1.3141/lib/' to $:
# ( 2 + ( 3 * a ) )
```

# GUI Application を配布する

さて，これで配布ができたとは言え， console application なんてやっぱり一般ユーザからしてみれば，あまり好ましくありません．
そこで，簡単な GUI Application を作成してみましょう．

Ruby で GUI Application を作る方法はいくつかありますが，僕としては [JRubyFX](https://github.com/jruby/jrubyfx) をオススメします．
`JRubyFX` は `JavaFX 2.2+` の wrapper として動作しているのですが， ruby の `method_missing` のような動的に解決できる手法を用いて `JavaFX` に対応しています．
今回は用いませんが， `.fxml` 形式による UI の作成や `.css` による layout の変更なども行えるので，かなり簡単に GUI Application が作成できると思います．
詳しくは [Getting Started](https://github.com/jruby/jrubyfx/wiki/Getting-Started) や [Sample Code](https://github.com/jruby/jrubyfx/tree/master/samples) をご覧下さい．また， `JavaFX` 自体については [JavaFX 2で始めるGUI開発](http://itpro.nikkeibp.co.jp/article/COLUMN/20120731/413043/?ST=develop) が役立つと思います．この ITpro の introduction を一通り `JRubyFX` で書き換えれば，たいていの GUI Application は作れるかと思います．

## JRubyFX の導入と Program の作成

```bash
$ jruby -S gem install jrubyfx
$ jruby -S gem install -i lib/ruby jrubyfx --no-rcod --no-ri
$ vim build_configuration.rb
$ mv src/dydx_test.rb src/jrubyfx_test.rb
$ vim src/jrubyfx_test.rb
$ jruby src/jrubyfx_test.rb
```

https://gist.github.com/huyu398/1660d0ead7189d5a5be3/d81410b16411e9c9e3ab5d7905515152fb98e761

これで，このような画面が表示されると思います．
![Hello World!_001.png](https://qiita-image-store.s3.amazonaws.com/0/19126/5578d14e-2a4c-8d8b-3122-8df8b54d5574.png) 

では，またいつも通りの Packaging です．

```bash
$ jruby -S rake rawr:clean
$ jruby -S rake rawr:jar
$ java -jar package/jar/rawr_test.jar
# Add 'src/' to $:
# Add 'lib/ruby/gems/jrubyfx-1.1.0-java/lib/' to $:
# Add 'lib/ruby/gems/jrubyfx-fxmlloader-0.3-java/lib/' to $:
```

同様の画面が表示されたと思います．

# おまけ

僕は Main PC を Ubuntu にしていて， Windows はただの Media Player として使用しているのですが， Linux 上で動くまともな Twitter Client がないのが悩みでした．
`Hotot` という vim like な操作ができる Twitter Client があるにはあるのですが， Chrome Plugin な上に，開発が終了してしまったため，あまり好ましくありません．

仕方がないので， Ruby で自作しようと思い立ちました．[RubyでGUIアプリを作るならJRuby+JavaFX+Rawrで決まり！](http://blog.supermomonga.com/articles/jruby/javafx-rawr.html) という記事を見つけ， Vim のことでもよく見ている Blog なので，この方面で進めてみようと考えました．
しかし， `rawr` の Packaging で躓いてしまい，仕方ないので公式に尋ねてみたら，依存 gem  の解決がうまく行っていないようだったので，上記の方法を試したところ上手く行ったのでどうせなら記事にまとめようという次第です．

また，この動機となった Twitter Client on Linux の Project がこれです（まだ Develop branch 上でのみ開発中）． [Rubbitter](https://github.com/huyu398/Rubbitter)

ちなみに，先のブログのように WebView が表示できることも確認できています．

```bash
$ vim src/jrubyfx_test.rb
$ jruby -S rake rawr:clean
$ jruby -S rake rawr:jar
$ java -jar package/jar/rawr_test.jar
```

https://gist.github.com/huyu398/1660d0ead7189d5a5be3/ac31ebd7f4d102558998fa53e9e0f36780961c75

![Hello JRubyFX_002.png](https://qiita-image-store.s3.amazonaws.com/0/19126/d6916cd9-ca68-2dc8-3c48-73632f62a20a.png)