JRuby on Rails on GAE/J 動いた

 
いまさら注記
$JRUBY_HOME/binはPATHの最後に追加して、ruby絡みのコマンドをjrubyで使うときはjruby -Sするのが正解ぽいです。

set $PATH=$PATH:$JRUBY_HOME/bin

で、例えばこんな感じ

jruby -S gem install rails

 

http://itrain.appspot.com/

基本的には昨日のエントリに書いてある通りだけど、もうちょっとだけ詳細に書いてみる。実際に試したいなら昨日のよりこっち見た方がいいと思う。ただしDataStoreもUsersServiceもなしで単にコントローラーでrender :text=>'hoge'するだけ。

まずJRubyインストール

リポジトリから最新を取って来て入れること。手を抜いて古いの入れるとたぶん動かない。

$ svn co http://svn.codehaus.org/jruby/trunk/jruby jruby
$ cd jruby
$ mvn
$ set JRUBY_HOME=xxx
$ set PATH=$JRUBY_HOME/bin:$PATH
$ jruby -v
jruby 1.3.0 (ruby 1.8.6p287) (2009-04-09 r6586) (Java HotSpot(TM) Client VM 1.5.0_16) [i386-java]

3行目でmavenじゃなくてantを使うと、後で必要になるjruby-complete.jarが作られなくて困ったことになるので注意。

Railsインストール

$ jruby/bin/gem install rails -y --no-ri --no-rdoc

Railsアプリ生成

GEM_HOMEを設定しておかないと、crubyのgemと干渉するのかなんなのか、私の環境ではよく分からないことになった。あと、-f を忘れずに。

$ GEM_HOME=$JRUBY_HOME/lib/ruby/gems/1.8/gems jruby $JRUBY_HOME/bin/rails im_jruby_on_rails -f
$ cd im_jruby_on_rails
$ ./script/generate controller welcome

コントローラーの中身は適当にこんな感じで。

# app/contrllers/welcome_controller.rb
class WelcomeController < ApplicationController
  def index
    render :text => "I'm JRuby on Rails."
  end
end

あとルートをwelcome/indexにしとく

# config/routes.rb
map.root :controller => "welcome"

さらに今のところprotect_from_forgeryが動かないらしいので、そこはコメントアウト

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  helper :all # include all helpers, all the time
  #protect_from_forgery # See ActionController::RequestForgeryProtection for details
end

なんならこの辺で

$ script/server

して http://localhost:3000/ を確認するのもよいかと。


以降の作業で、このアプリをGAE上に乗っけます。

不要なファルを削除

GAEにアップできるファイルは1000ファイルまでだそうなので、不要なファイルはがっつり消さないとエラーになる。私が消したのは以下。アプリによってはこのとおり消すとまずいものもあるかも。

$ rm -rf test/
$ rm -rf doc/
$ rm -rf vendor/rails/activerecord/
$ rm -rf vendor/rails/activeresource/
$ rm -rf vendor/rails/actionmailer/
$ rm -rf vendor/rails/railties/doc/
$ rm -rf vendor/rails/railties/html/
$ rm -rf vendor/rails/railties/bin/
$ rm -rf vendor/rails/railties/builtin/
$ rm -rf vendor/rails/railties/environments/
$ rm -rf vendor/rails/railties/dispatches/
$ rm -rf vendor/rails/actionpack/test/
$ rm public/index.html

消したファイルを使わないようにconfigを修正

# config/environment.rb
config.frameworks -= [ :active_record, :active_resource, :action_mailer ]

appengine-web.xmlファイル編集

system-propertiesの詳細はよく分かってないけど昨日のエントリの通り

<?xml version="1.0" encoding="utf-8"?>
<!-- appengine-web.xml -->
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
    <application>YOUR_APP_NAME</application>
    <version>1</version>

    <system-properties>
        <property name="jruby.management.enabled" value="false" />
        <property name="os.arch" value="" />
    </system-properties>
</appengine-web-app>

YOUR_APP_NAMEは自分がGAEに登録したアプリ名にすること。

必要なjarファイルをlib以下に置く

AppEngine Java SDK

http://code.google.com/intl/en/appengine/downloads.html

$ wget http://googleappengine.googlecode.com/files/appengine-java-sdk-1.2.0.zip
$ unzip appengine-java-sdk-1.2.0.zip
$ cp appengine-java-sdk-1.2.0/lib/user/appengine-api-1.0-sdk-1.2.0.jar $RAILS_ROOT/lib
JRuby-Rack最新版

ちゃんとgitから最新を入れよう。

$ git clone git://github.com/nicksieger/jruby-rack.git
$ jruby -S rake SKIP_SPECS=true
$ mv target/jruby-rack-0.9.4-SNAPSHOT.jar $RAILS_ROOT/lib/
JRuby

ちょっと面倒くさいけど昨日のエントリの通り。$JRUBY_HOME/lib/jruby-complete.jarを取って来て、以下のスクリプトをファイルに保存。`chmod +x'してから実行。

#!/bin/sh

rm -rf jruby-core.jar
rm -rf ruby-stdlib.jar
rm -rf tmp_unpack
mkdir tmp_unpack
cd tmp_unpack
jar xf ../jruby-complete.jar
cd ..
mkdir jruby-core
mv tmp_unpack/org jruby-core/
mv tmp_unpack/com jruby-core/
mv tmp_unpack/jline jruby-core/
mv tmp_unpack/jay jruby-core/
mv tmp_unpack/jruby jruby-core/
cd jruby-core
jar cf ../jruby-core.jar .
cd ../tmp_unpack
jar cf ../ruby-stdlib.jar .
cd ..
rm -rf jruby-core
rm -rf tmp_unpack
rm -rf jruby-complete.jar

jruby-core.jarとruby-stdlib.jarができるのでlib以下に置く。

warblerインストール

warblerはwarを簡単に作ってくれるツールらしい。以下はRailsアプリのルートで実行すること

$ jruby -S gem install warbler
$ jruby -S warble pluginize
$ jruby -S warble config

warblerの設定ファイル編集

昨日の例ではincludesにdatastore-indexes.xmlを含めてたけど、今回のはDataStoreを使わないので含めない。

# config/warble.rb
Warbler::Config.new do |config|
  config.dirs = %w(app config lib log vendor tmp) # default
  config.includes = FileList["appengine-web.xml"]
  config.java_libs = []
  config.gem_dependencies = true                  # default
  config.webxml.jruby.min.runtimes = 1
  config.webxml.jruby.max.runtimes = 1
  config.webxml.jruby.init.serial = true
end

$RAILS_ROOTでwarbleコマンド実行

$ warble war

tmp/warの下にいい感じにファイルが配備される。生成されるim_jruby_on_rails.jarは使わない。

GAE上にデプロイ

$ appengine-java-sdk-1.2.0/bin/appcfg.sh update tmp/war
Reading application configuration data...
2009-04-09 02:35:34.408::INFO:  Logging to STDERR via org.mortbay.log.StdErrLog
Beginning server interaction for itrain...
0% Creating staging directory
5% Scanning for jsp files.
20% Scanning files on local disk.
...snip...
98% Closing update: new version is ready to start serving.
99% Uploading index definitions.
Update complete.
Success.
Cleaning up temporary files...

確認

http://itrain.appspot.com

エラーがあった場合はコンソール( http://appengine.google.com )でログを確認できる。