NetBeans上で、RackとSinatraを使いJRubyを動かす

NetBeansを使うと、JRuby On Railsアプリケーションが嘘みたいに簡単に作れます。
http://www.netbeans.org/kb/docs/ruby/rapid-ruby-weblog.html
内蔵のGlassFishでさくっと動かせるし、Warblerを使えばwar化出来るので、デブロイするのも簡単です。
しかし簡単すぎて、Railsを使うまでもない、ちょっとしたCGIレベルのアプリケーションを作ろうとすると逆に難しく感じてしまいます。
JRubyサーブレットを書くのは以下の記事が参考になりますが、フレームワークを使ってもう少し簡単に動かしたいところです。
http://www.okisoft.co.jp/esc/ruby/jservlet/index.html

Rackを使う事にする

RubyにはRackと呼ばれる有名なライブラリがあり、これを使うとサーバの違いを気にする事無くWebアプリを作る事が可能です。
http://route477.net/d/?date=20080716
JRuby用のJRuby-Rackという物も作られていて、同じ書式でRack用のWebアプリを作成出来ます。これもサーバの違い(JRubyの場合はTomcatGlassFishやらのJ2EEサーバ)を気にしなくても良いのと、サーブレットへのアダプタとしても動いてくれるので、理論上はRack用に作られているRubyアプリケーションはJRubyでも簡単に動かせます。NetBeansJRuby On Railsプロジェクトは、これを使って動くように作成されます。素のRuby On Railsも最近はRackが使われてますよね。
つまりRackで動くように書けばJRubyでも動かせます。これでサーブレットをゴリゴリ書く必要が無くなり、随分と楽をすることが可能になります。

Sinatraを使って更に楽をする

RackにはSinatraと呼ばれるミドルウェアがあり、シンプルなRackを更にシンプルにする事が出来ます。
http://labs.unoh.net/2009/05/sinatra.html
RubyRailsを使うまでもない場合に最適ですが、JRubyでも同じってことです。

NetBeans上で使ってみる

NetBeansではJ2EEアプリのひな形の作成と、内蔵されているGrassFishへのデブロイも簡単に出来るので、JRuby & Sinatra環境を構築してみます。Railsと違いプロジェクトのテンプレートが用意されているわけではないので、多少は手動でごにょごにょする必要はあります。

プロジェクトの作成

新規プロジェクトの作成で、Java WebのWeb アプリケーションをひな形にして作成します。

プロジェクト名とかは適当に。そのままWebApplication1として作成しました。

デフォルトのままです。GlassFish V3を使います。

ここもデフォルトです。ここに出てるフレームワークは使いません。これで完了です。

ライブラリの追加

JRubyJRuby-Rackのjarファイルを用意します。
JRubyは、http://jruby.org/download/ からjruby-complete.jarをダウンロードしてきます。必要なのはcompleteが付いてるものです。今回は最新バージョンの、http://dist.codehaus.org/jruby/1.3.1/jruby-complete-1.3.1.jar をダウンロードしました。
Rackは、http://kenai.com/projects/jruby-rack/pages/Home#Download からjruby-rack.jarをダウンロードしてきます。今回は最新バージョンの、 http://kenai.com/downloads/jruby-rack/jruby-rack-0.9.5.jar をダウンロードしました。
用意した2つのjarファイルを、プロジェクトのライブラリとして追加します。プロジェクトプロパティのライブラリで追加しています。

gemの追加

Sinatraはgemからインストールします。JRuby-Rackは何も指定しないとWEB-INF/gemsディレクトリにgemがインストールされているとみなします。NetBeansで作成したWebApplicationにはgemsディレクトリは作られていないので、自分で作成してやる必要があります。
作成したgemsディレクトリに対してsinatraのgemをインストールします。普通にjrubyを使っても良いですが、先ほどダウンロードしてきたjruby-complete.jarを使うことも出来ます。NetBeansはgemの管理も出来るのですが、今回はコマンドラインから手動で追加しました。

java -jar WebApplication1/lib/jruby-complete-1.3.1.jar -S gem install -i WebApplication1/web/WEB-INF/gems/ sinatra --no-ri --no-rdoc

gem installに-iオプションを付けてインストールディレクトリを指定しています。他にもgemを使いたい場合は、同じように追加していけばOKです。

サンプル用のSinatraRubyプログラムを作成

WEB-INF直下にdemo.rbとして作成しました。

require 'rubygems'
require 'sinatra'

get '/' do
    'Hello world!'
end

get '/test/' do
    'Hello Test'
end

ここまでで、ディレクトリ構造はこんな感じになってます。
webの下にindex.jspが作成されていたのですが、邪魔なので消してます。

web.xmlの編集

最後にweb.xmlを編集します。ほとんどJRuby-Rackのサンプルをコピーしてきました。通常Rackのアプリを動かす時にruファイルを作成しますが、その内容をrackupのパラメータにて設定する感じです。

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <context-param>
        <param-name>rackup</param-name>
        <param-value>
            require 'rubygems'
            gem 'sinatra', '~&gt; 0.9'
            require './demo'
            set :run, false
            set :environment, :production
            run Sinatra::Application
        </param-value>
    </context-param>

    <filter>
        <filter-name>RackFilter</filter-name>
        <filter-class>org.jruby.rack.RackFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>RackFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <listener>
        <listener-class>org.jruby.rack.RackServletContextListener</listener-class>
    </listener>
</web-app>

動作チェック

これにて完了です。あとはWebサーバを起動すれば確認することが出来ます。NetBeansでプロジェクトを右クリック、実行で配備出来ます。
http://localhost:8080/WebApplication1/ にアクセスすればdemo.rbにて作成したものが表示されます。

使いどころ

J2EEで動かすのでパフォーマンスはかなり良いです。CGIと比べると圧倒的だと思います。
起動してしまえば早いのですが、起動完了まで時間がかかります。あと、ソースを修正する度にアプリケーションの再起動が必要なので、開発に使うには厳しいです。普段は素のRubyで動かしておいて、最終的にJ2EE上にデブロイするのが上手いやり方だと思います。
これだけだと手間がかかるだけで魅力的に感じませんが、Google App Engine上で動かす方法が確立されているので、それについてはかなり魅力的だと思います。
http://jugyo.org/blog/3388