2009-10-23
■ [Java][JRuby][Sinatra] Scanty on GAE/J

Rubyの軽量Webアプリケーションフレームワーク「Sinatra」で実装されたブログエンジン「Scanty」を、Google App Engine for Java上でJRubyを使って動かすための、自分用のメモだよ。
ここでの手順は、Debian GNU/Linux 5.0.3 (lenny)で行うことを想定しているよ。
Java SDKのインストール
まだJava SDKをインストールしていない人は、インストールしてね。インストールするには/etc/apt/sources.listの
deb http://ftp.jp.debian.org/debian/ lenny main
となっているところにnon-freeを追加して、
deb http://ftp.jp.debian.org/debian/ lenny main non-free
そのあと「apt-get install sun-java6-jdk」と入力すればインストールできるよ。
# apt-get install sun-java6-jdk
Google App Engine for Java SDKのダウンロードと展開
まだGoogle App Engine for Java SDKを入手していない人は、ダウンロードしてね。Linuxの場合、wgetコマンドでダウンロードするのが便利だよ。まだwgetコマンドをインストールしていない場合は、
# apt-get install wget
としてインストールしてね。あと、zipファイルの展開にはunzipコマンドが必要だから、同様に
# apt-get install unzip
としてインストールしてね。wgetコマンドとunzipコマンドが使えるようになったら、次のようにコマンドを入力して展開してね。
$ cd ~ $ wget http://googleappengine.googlecode.com/files/appengine-java-sdk-1.2.6.zip $ unzip appengine-java-sdk-1.2.6.zip
scantyディレクトリの作成
$ cd ~ $ mkdir scanty $ cd scanty
Scantyのソースコードの入手
Scantyのソースコードを入手するにはgitコマンドが必要だよ。まだgitコマンドをインストールしていない場合は、
# apt-get install git-core
としてインストールしてね。Google App Engineにデプロイするので、WEB-INFというディレクトリ名でgit cloneするよ。
$ git clone git://github.com/adamwiggins/scanty.git WEB-INF
jruby-complete-1.4.0RC1.jarのダウンロード
$ wget http://dist.codehaus.org/jruby/1.4.0RC1/jruby-complete-1.4.0RC1.jar
Scantyを動作させるのに必要なgemのインストール
JRubyのgemコマンドを使って、必要となるライブラリを入手するよ。
$ mkdir WEB-INF/gems $ java -jar jruby-complete-1.4.0RC1.jar -S gem install -i WEB-INF/gems sinatra --no-ri --no-rdoc $ java -jar jruby-complete-1.4.0RC1.jar -S gem install -i WEB-INF/gems dm-core --version 0.9.11 --no-ri --no-rdoc $ java -jar jruby-complete-1.4.0RC1.jar -S gem install -i WEB-INF/gems dm-aggregates --version 0.9.11 --no-ri --no-rdoc $ java -jar jruby-complete-1.4.0RC1.jar -S gem install -i WEB-INF/gems dm-types --version 0.9.11 --no-ri --no-rdoc $ java -jar jruby-complete-1.4.0RC1.jar -S gem install -i WEB-INF/gems dm-datastore-adapter --no-ri --no-rdoc $ java -jar jruby-complete-1.4.0RC1.jar -S gem install -i WEB-INF/gems builder --no-ri --no-rdoc $ rm WEB-INF/gems/cache/*
jruby-core.jarとruby-stdlib.jarをlibフォルダに作成
次のようにコマンドを入力して、「jruby-complete-1.4.0RC1.jar」から「jruby-core.jar」と「ruby-stdlib.jar」を作成するよ。ここでは元となる「jruby-complete-1.4.0RC1.jar」は削除しているけど、削除したくない人は他のディレクトリにコピーしておいてね。
$ mkdir tmp_unpack $ cd tmp_unpack $ jar xf ../jruby-complete-1.4.0RC1.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 $ mv jruby-core.jar WEB-INF/lib $ mv ruby-stdlib.jar WEB-INF/lib $ rm jruby-complete-1.4.0RC1.jar
appengine-api-1.0-sdk-1.2.6.jarのコピー
次のコマンドを入力して、「appengine-api-1.0-sdk-1.2.6.jar」ファイルをコピーするよ。
$ cp ../appengine-java-sdk-1.2.6/lib/user/appengine-api-1.0-sdk-1.2.6.jar WEB-INF/lib
jruby-rack-0.9.5.jarのダウンロード
$ wget http://kenai.com/projects/jruby-rack/downloads/download/jruby-rack-0.9.5.jar $ mv jruby-rack-0.9.5.jar WEB-INF/lib
ソースコードにパッチを適用
テキストエディタで次の内容のファイルをscanty_gae_patch.diffという名前で保存してね。
diff -cr scanty_orig/lib/post.rb scanty_gae/lib/post.rb
*** scanty_orig/lib/post.rb 2009-10-23 15:16:31.000000000 +0900
--- scanty_gae/lib/post.rb 2009-10-23 15:08:46.000000000 +0900
***************
*** 1,20 ****
require File.dirname(__FILE__) + '/../vendor/maruku/maruku'
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../vendor/syntax'
require 'syntax/convertors/html'
! class Post < Sequel::Model
! unless table_exists?
! set_schema do
! primary_key :id
! text :title
! text :body
! text :slug
! text :tags
! timestamp :created_at
! end
! create_table
! end
def url
d = created_at
--- 1,28 ----
+ gem "dm-core", "0.9.11"
+
+ require 'dm-core'
+ require 'dm-aggregates'
+ require 'dm-types'
+ require 'dm-datastore-adapter/datastore-adapter'
+
+ DataMapper.setup(:datastore,
+ :adapter => :datastore,
+ :database => 'posts')
+
require File.dirname(__FILE__) + '/../vendor/maruku/maruku'
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../vendor/syntax'
require 'syntax/convertors/html'
! class Post
! include DataMapper::Resource
! def self.default_repository_name; :datastore end
! property :id, Serial
! property :title, Text, :lazy => false
! property :body, Text, :lazy => false
! property :slug, Text, :lazy => false
! property :tags, Text, :lazy => false
! property :created_at, DateTime
def url
d = created_at
diff -cr scanty_orig/main.rb scanty_gae/main.rb
*** scanty_orig/main.rb 2009-10-23 15:16:31.000000000 +0900
--- scanty_gae/main.rb 2009-10-23 15:08:48.000000000 +0900
***************
*** 1,11 ****
require 'rubygems'
require 'sinatra'
! $LOAD_PATH.unshift File.dirname(__FILE__) + '/vendor/sequel'
! require 'sequel'
configure do
! Sequel.connect(ENV['DATABASE_URL'] || 'sqlite://blog.db')
require 'ostruct'
Blog = OpenStruct.new(
--- 1,11 ----
require 'rubygems'
require 'sinatra'
! #$LOAD_PATH.unshift File.dirname(__FILE__) + '/vendor/sequel'
! #require 'sequel'
configure do
! #Sequel.connect(ENV['DATABASE_URL'] || 'sqlite://blog.db')
require 'ostruct'
Blog = OpenStruct.new(
***************
*** 44,55 ****
### Public
get '/' do
! posts = Post.reverse_order(:created_at).limit(10)
erb :index, :locals => { :posts => posts }, :layout => false
end
get '/past/:year/:month/:day/:slug/' do
! post = Post.filter(:slug => params[:slug]).first
stop [ 404, "Page not found" ] unless post
@title = post.title
erb :post, :locals => { :post => post }
--- 44,56 ----
### Public
get '/' do
! posts = Post.all(:limit => 10, :order => [:created_at.asc])
! # posts = Post.all(:order => [:created_at.asc])
erb :index, :locals => { :posts => posts }, :layout => false
end
get '/past/:year/:month/:day/:slug/' do
! post = Post.first(:slug => params[:slug])
stop [ 404, "Page not found" ] unless post
@title = post.title
erb :post, :locals => { :post => post }
***************
*** 60,79 ****
end
get '/past' do
! posts = Post.reverse_order(:created_at)
@title = "Archive"
erb :archive, :locals => { :posts => posts }
end
get '/past/tags/:tag' do
tag = params[:tag]
! posts = Post.filter(:tags.like("%#{tag}%")).reverse_order(:created_at).limit(30)
@title = "Posts tagged #{tag}"
erb :tagged, :locals => { :posts => posts, :tag => tag }
end
get '/feed' do
! @posts = Post.reverse_order(:created_at).limit(20)
content_type 'application/atom+xml', :charset => 'utf-8'
builder :feed
end
--- 61,80 ----
end
get '/past' do
! posts = Post.all(:order => [:created_at.asc])
@title = "Archive"
erb :archive, :locals => { :posts => posts }
end
get '/past/tags/:tag' do
tag = params[:tag]
! posts = Post.all(:tags => tag, :limit => 30, :order => [:created_at.asc])
@title = "Posts tagged #{tag}"
erb :tagged, :locals => { :posts => posts, :tag => tag }
end
get '/feed' do
! @posts = Post.all(:limit => 20, :order => [:created_at.asc])
content_type 'application/atom+xml', :charset => 'utf-8'
builder :feed
end
***************
*** 107,120 ****
get '/past/:year/:month/:day/:slug/edit' do
auth
! post = Post.filter(:slug => params[:slug]).first
stop [ 404, "Page not found" ] unless post
erb :edit, :locals => { :post => post, :url => post.url }
end
post '/past/:year/:month/:day/:slug/' do
auth
! post = Post.filter(:slug => params[:slug]).first
stop [ 404, "Page not found" ] unless post
post.title = params[:title]
post.tags = params[:tags]
--- 108,121 ----
get '/past/:year/:month/:day/:slug/edit' do
auth
! post = Post.first(:slug => params[:slug])
stop [ 404, "Page not found" ] unless post
erb :edit, :locals => { :post => post, :url => post.url }
end
post '/past/:year/:month/:day/:slug/' do
auth
! post = Post.first(:slug => params[:slug])
stop [ 404, "Page not found" ] unless post
post.title = params[:title]
post.tags = params[:tags]
diff -cr scanty_orig/views/feed.builder scanty_gae/views/feed.builder
*** scanty_orig/views/feed.builder 2009-10-23 15:16:31.000000000 +0900
--- scanty_gae/views/feed.builder 2009-10-23 15:08:46.000000000 +0900
***************
*** 2,17 ****
xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
xml.title Blog.title
xml.id Blog.url_base
! xml.updated @posts.first[:created_at].iso8601 if @posts.any?
xml.author { xml.name Blog.author }
@posts.each do |post|
xml.entry do
! xml.title post[:title]
xml.link "rel" => "alternate", "href" => post.full_url
xml.id post.full_url
! xml.published post[:created_at].iso8601
! xml.updated post[:created_at].iso8601
xml.author { xml.name Blog.author }
xml.summary post.summary_html, "type" => "html"
xml.content post.body_html, "type" => "html"
--- 2,17 ----
xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
xml.title Blog.title
xml.id Blog.url_base
! xml.updated @posts.first.created_at if @posts.any?
xml.author { xml.name Blog.author }
@posts.each do |post|
xml.entry do
! xml.title post.title
xml.link "rel" => "alternate", "href" => post.full_url
xml.id post.full_url
! xml.published post.created_at
! xml.updated post.created_at
xml.author { xml.name Blog.author }
xml.summary post.summary_html, "type" => "html"
xml.content post.body_html, "type" => "html"
diff -cr scanty_orig/views/index.erb scanty_gae/views/index.erb
*** scanty_orig/views/index.erb 2009-10-23 15:16:31.000000000 +0900
--- scanty_gae/views/index.erb 2009-10-23 15:08:46.000000000 +0900
***************
*** 16,23 ****
<div id="content">
<% posts.each do |post| %>
<div class="post">
! <p class="date"><%= post[:created_at].strftime("%b") %><b><%= post[:created_at].strftime("%d") %></b></p>
! <h2 class="title"><a href="<%= post.url %>"><%= post[:title] %></a></h2>
<p class="meta"><small>
<%= post.linked_tags %>
<% if Blog.disqus_shortname %>
--- 16,23 ----
<div id="content">
<% posts.each do |post| %>
<div class="post">
! <p class="date"><%= post.created_at.strftime("%b") %><b><%= post.created_at.strftime("%d") %></b></p>
! <h2 class="title"><a href="<%= post.url %>"><%= post.title %></a></h2>
<p class="meta"><small>
<%= post.linked_tags %>
<% if Blog.disqus_shortname %>
diff -cr scanty_orig/views/tagged.erb scanty_gae/views/tagged.erb
*** scanty_orig/views/tagged.erb 2009-10-23 15:16:31.000000000 +0900
--- scanty_gae/views/tagged.erb 2009-10-23 15:08:46.000000000 +0900
***************
*** 1,8 ****
<h1>Posts tagged <%= tag %></h1>
<% posts.each do |post| %>
<div class="post">
! <p class="date"><%= post[:created_at].strftime("%b") %><b><%= post[:created_at].strftime("%d") %></b></p>
! <h2 class="title"><a href="<%= post.url %>"><%= post[:title] %></a></h2>
<p class="meta"><small><%= post.linked_tags %> | <a href="<%= post.url %>#disqus_thread">comments</a></small></p>
<div class="entry">
<%= post.summary_html %>
--- 1,8 ----
<h1>Posts tagged <%= tag %></h1>
<% posts.each do |post| %>
<div class="post">
! <p class="date"><%= post.created_at.strftime("%b") %><b><%= post.created_at.strftime("%d") %></b></p>
! <h2 class="title"><a href="<%= post.url %>"><%= post.title %></a></h2>
<p class="meta"><small><%= post.linked_tags %> | <a href="<%= post.url %>#disqus_thread">comments</a></small></p>
<div class="entry">
<%= post.summary_html %>
次のコマンドでパッチを適用してね。
$ patch -p1 -d WEB-INF < scanty_gae_patch.diff
WEB-INF/appengine-web.xmlの作成
テキストエディタで次の内容を入力して、WEB-INFディレクトリの中にappengine-web.xmlという名前で保存してね。
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>scanty</application>
<version>1</version>
<static-files>
<include path="/public/**.*" />
</static-files>
<resource-files />
<sessions-enabled>false</sessions-enabled>
<system-properties>
<property name="jruby.management.enabled" value="false" />
<property name="os.arch" value="" />
<property name="jruby.compile.mode" value="JIT"/> <!-- JIT|FORCE|OFF -->
<property name="jruby.compile.fastest" value="true"/>
<property name="jruby.compile.frameless" value="true"/>
<property name="jruby.compile.positionless" value="true"/>
<property name="jruby.compile.threadless" value="false"/>
<property name="jruby.compile.fastops" value="false"/>
<property name="jruby.compile.fastcase" value="false"/>
<property name="jruby.compile.chainsize" value="500"/>
<property name="jruby.compile.lazyHandles" value="false"/>
<property name="jruby.compile.peephole" value="true"/>
</system-properties>
</appengine-web-app>
WEB-INF/web.xmlの作成
テキストエディタで次の内容を入力して、WEB-INFディレクトリの中にweb.xmlという名前で保存してね。
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<context-param>
<param-name>public.root</param-name>
<param-value>/</param-value>
</context-param>
<context-param>
<param-name>rackup</param-name>
<param-value>require 'rubygems'
require 'sinatra'
root_dir = File.dirname(__FILE__)
#set :environment, :production
set :environment, :development
set :root, root_dir
set :app_file, File.join(root_dir, 'main.rb')
disable :run
require 'main'
run Sinatra::Application
</param-value>
</context-param>
<context-param>
<param-name>jruby.min.runtimes</param-name>
<param-value>1</param-value>
</context-param>
<context-param>
<param-name>jruby.max.runtimes</param-name>
<param-value>1</param-value>
</context-param>
<context-param>
<param-name>jruby.init.serial</param-name>
<param-value>true</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>
開発用サーバの起動
次のコマンドを入力して、開発用サーバを起動してね。
$ ../appengine-java-sdk-1.2.6/bin/dev_appserver.sh .
Webブラウザで開発用サーバにアクセス
http://localhost:8080/にアクセスして、動作確認してね。デフォルトではログインパスワードは「changeme」だよ。
Google App Engineにデプロイ
「appengine-web.xml」の「application」と「version」を適切に設定して、次のコマンドを実行してね。
$ ../appengine-java-sdk-1.2.6/bin/appcfg.sh update .
2009-08-23
■ [Java][JRuby][Ramaze] 「Ramazeを使って120行で作る単語帳アプリ」 on GAE/J

「Ruby Freaks Lounge:第12回 Ramazeを使って120行で作る単語帳アプリ|gihyo.jp … 技術評論社」という記事にある単語帳アプリを、Google App Engine for Java上でJRubyを使って動かすための、自分用のメモだよ。
ここでの手順は、Windowsで行うことを想定しているよ。
あと、残念ながらバリデーションがうまく動かなかったから、ここでの例では同じ単語を複数登録することができてしまうよ。
Java SDKのダウンロードとインストール
まだJava SDKをインストールしていない人は、ダウンロードしてインストールしてね。
Java SDKをインストールするには、Java SDKのダウンロードサイトにアクセスして、下のほうにある「JDK 6 Update 16」の右側の「Download」をクリックしてね。Platformは「Windows」を選択してね。
ダウンロードしたインストーラ「jdk-6u16-windows-i586.exe」をダブルクリックすると、インストールが始まるよ。
Google App Engine for Java SDKのダウンロードと展開
まだGoogle App Engine for Java SDKを入手していない人は、ダウンロードしてね。
Google App Engine for Java SDKを入手するには、Google App Engineのダウンロードサイトにアクセスして、「appengine-java-sdk-1.2.2.zip」をクリックしてダウンロードしてね。ダウンロードした「appengine-java-sdk-1.2.2.zip」ファイルは圧縮されているから、Cドライブ直下に展開してね。
ramazewordsディレクトリの作成
コマンドプロンプトを起動して、次のようにコマンドを入力してね
空白を含むパス上だとうまく動かないみたいなので、ここではCドライブ直下に作成しているよ
> cd \ > mkdir ramazewords > cd \ramazewords
jruby-complete-1.3.1.jarのダウンロードと設置
まだ「jruby-complete-1.3.1.jar」を入手していない人は、ダウンロードしてね。入手先はJRubyのサイトだよ。
「jruby-complete-1.3.1.jar」をクリックしてダウンロードしたら、先ほど作ったC:\ramazewordsフォルダに配置してね。
WEB-INFフォルダの作成
先ほど作った「ramazewords」ディレクトリの中に、次のように3つのディレクトリを作成するよ。
> mkdir WEB-INF > mkdir WEB-INF\gems > mkdir WEB-INF\lib
Ramaze、DataMapperのインストール
JRubyのgemコマンドを使って、必要となるライブラリを入手するよ。
> set JAVA_HOME=C:\PROGRA~1\Java\jdk1.6.0_16 > set PATH=%JAVA_HOME%\bin;C:\appengine-java-sdk-1.2.2\bin;%PATH% > java -jar jruby-complete-1.3.1.jar -S gem install -i WEB-INF\gems ramaze --no-ri --no-rdoc > java -jar jruby-complete-1.3.1.jar -S gem install -i WEB-INF\gems addressable --no-ri --no-rdoc > java -jar jruby-complete-1.3.1.jar -S gem install -i WEB-INF\gems dm-datastore-adapter --no-ri --no-rdoc > java -jar jruby-complete-1.3.1.jar -S gem install -i WEB-INF\gems dm-validations --no-ri --no-rdoc > rmdir /s /q WEB-INF\gems\bin > del /q WEB-INF\gems\cache\*
jruby-core.jarとruby-stdlib.jarをlibフォルダに作成
次のようにコマンドを入力して、「jruby-complete-1.3.1.jar」から「jruby-core.jar」と「ruby-stdlib.jar」を作成するよ。ここでは元となる「jruby-complete-1.3.1.jar」は削除しているけど、削除したくない人は他のフォルダにコピーしておいてね。
> mkdir tmp_unpack > cd tmp_unpack > jar xf ../jruby-complete-1.3.1.jar > cd .. > mkdir jruby-core > move tmp_unpack\org jruby-core > move tmp_unpack\com jruby-core > move tmp_unpack\jline jruby-core > move tmp_unpack\jay jruby-core > move tmp_unpack\jruby jruby-core > cd jruby-core > jar cf ../jruby-core.jar . > cd ..\tmp_unpack > jar cf ../ruby-stdlib.jar . > cd .. > rmdir /s /q jruby-core > rmdir /s /q tmp_unpack > move jruby-core.jar WEB-INF\lib > move ruby-stdlib.jar WEB-INF\lib > del jruby-complete-1.3.1.jar
appengine-api-1.0-sdk-1.2.2.jarのコピー
次のコマンドを入力して、「appengine-api-1.0-sdk-1.2.2.jar」ファイルをコピーするよ。
> copy C:\appengine-java-sdk-1.2.2\lib\user\appengine-api-1.0-sdk-1.2.2.jar WEB-INF\lib
jruby-rack-0.9.5-SNAPSHOT.jarのダウンロードと配置
こちらのサイトから「jruby-rack-0.9.5-SNAPSHOT.jar」をダウンロードして、C:\ramazewords\WEB-INF\libに配置してね。ダウンロードは右下のほうの「raw」というリンクをクリックしてね。
WEB-INF/app.rbの作成
テキストエディタで次の内容を入力して、WEB-INFフォルダの中にapp.rbという名前で保存してね。
require 'rubygems' require 'ramaze' require 'dm-core' require 'dm-aggregates' require 'dm-types' require 'dm-datastore-adapter/datastore-adapter' #require 'dm-validations' # Model DataMapper.setup(:datastore, :adapter => :datastore, :database => 'words') class Word include DataMapper::Resource def self.default_repository_name; :datastore end property :id, Serial property :name, String property :description, Text, :lazy => false # validates_is_unique :name end #DataMapper.auto_upgrade! # Controller class WordController < Ramaze::Controller map '/' engine :ERB layout 'default' def index @words = Word.all end def new end def create word = Word.create( :name => request[:name], :description => request[:description] ) if word redirect r(:show, word.id) else redirect_referer end end def show(id) @word = Word.get(id) end def delete(id) redirect_referer unless request.post? word = Word.get(id) if word word.destroy redirect r(:index) else redirect_referer end end def random at = rand(Word.count) @word = Word.first(:offset => at) render_view :show end end
WEB-INF/layout/default.html.erbの作成
テキストエディタで次の内容を入力して、WEB-INFフォルダの中にlayoutフォルダを作成して、そこにdefault.html.erbという名前で保存してね。あ、このファイルは日本語を含んでいるから、ファイルを保存するときは文字コードを「UTF-8」に設定してね。
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>単語帳</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="/screen.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/jquery-1.3.2.min.js" />
</head>
<body>
<h1>単語帳</h1>
<%= @content %>
</body>
</html>
WEB-INF/view/index.html.erbの作成
テキストエディタで次の内容を入力して、WEB-INFフォルダの中にviewフォルダを作成して、そこにindex.html.erbという名前で保存してね。このファイルも日本語を含んでいるから、ファイルを保存するときは文字コードを「UTF-8」に設定してね。
<h2>単語一覧</h2>
<div class="box"><ul>
<% @words.each do |word| %>
<li><%= a(word.name, :show, word.id) %></li>
<% end %>
</ul>
</div>
<ul>
<li><%= a("(新規作成)", :new) %></li>
<li><%= a("(ランダム表示)", :random) %></li>
</ul>
WEB-INF/view/new.html.erbの作成
テキストエディタで次の内容を入力して、WEB-INFフォルダの中のviewフォルダの中にnew.html.erbという名前で保存してね。このファイルも日本語を含んでいるから、ファイルを保存するときは文字コードを「UTF-8」に設定してね。
<h2>単語の追加</h2>
<form method="POST" action="create">
<ul>
<li>単語:<input type="text" name="name"></li>
<li>解説:<textarea name="description" cols="80" rows="10"></textarea></li>
<br/><input type="submit" value="登録">
</ul>
</form>
<%= a('キャンセル', :index) %>
WEB-INF/view/show.html.erbの作成
テキストエディタで次の内容を入力して、WEB-INFフォルダの中のviewフォルダの中にshow.html.erbという名前で保存してね。このファイルも日本語を含んでいるから、ファイルを保存するときは文字コードを「UTF-8」に設定してね。
<div class="box">
<h3><%=h @word.name %></h3>
<pre><%=h @word.description %></pre>
<a href="#" id="asdf">(削除)</a>
</div>
<%= a("一覧に戻る", :index) %>
<script type="text/javascript">
$(document).ready(function(){
$("#asdf").click(function(){
if(confirm('本当に?')){
$.post("<%= r(:delete, @word.id) %>", function(){
location.href = "<%= r(:index) %>";
});
}
});
});
</script>
WEB-INF/public/screen.cssの作成
テキストエディタで次の内容を入力して、WEB-INFフォルダの中にpublicフォルダを作成して、そこにscreen.cssという名前で保存してね。
body {
width: 60%;
padding-left: 20%;
}
h1, h2, form, .box {
border: 2px dashed black;
margin: 10px;
padding: 8px;
}
jquery-1.3.2.min.jsのダウンロードと配置
こちらのサイトから「jquery-1.3.2.min.js」ファイルをダウンロードして、C:\ramazewords\WEB-INF\publicに配置してね。
WEB-INF/appengine-web.xmlの作成
テキストエディタで次の内容を入力して、WEB-INFフォルダの中にappengine-web.xmlという名前で保存してね。
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>ramaze_on_gae</application>
<version>1</version>
<static-files>
<include path="/public/**.*" />
</static-files>
<resource-files />
<sessions-enabled>false</sessions-enabled>
<system-properties>
<property name="jruby.management.enabled" value="false" />
<property name="os.arch" value="" />
<property name="jruby.compile.mode" value="JIT"/> <!-- JIT|FORCE|OFF -->
<property name="jruby.compile.fastest" value="true"/>
<property name="jruby.compile.frameless" value="true"/>
<property name="jruby.compile.positionless" value="true"/>
<property name="jruby.compile.threadless" value="false"/>
<property name="jruby.compile.fastops" value="false"/>
<property name="jruby.compile.fastcase" value="false"/>
<property name="jruby.compile.chainsize" value="500"/>
<property name="jruby.compile.lazyHandles" value="false"/>
<property name="jruby.compile.peephole" value="true"/>
</system-properties>
</appengine-web-app>
WEB-INF/web.xmlの作成
テキストエディタで次の内容を入力して、WEB-INFフォルダの中にweb.xmlという名前で保存してね。
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<context-param>
<param-name>public.root</param-name>
<param-value>/</param-value>
</context-param>
<context-param>
<param-name>rackup</param-name>
<param-value>require 'rubygems'
class Thread
def Thread.exclusive
_old = Thread.critical
begin
Thread.critical = true
return yield
ensure
Thread.critical = _old
end
end
end
require 'ramaze'
require 'app'
Ramaze.start(:root => __DIR__, :started => true)
run Ramaze
</param-value>
</context-param>
<context-param>
<param-name>jruby.min.runtimes</param-name>
<param-value>1</param-value>
</context-param>
<context-param>
<param-name>jruby.max.runtimes</param-name>
<param-value>1</param-value>
</context-param>
<context-param>
<param-name>jruby.init.serial</param-name>
<param-value>true</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>
data_objects_adapterにモンキーパッチを適用
C:\ramazewords\WEB-INF\gems\gems\dm-aggregates-0.9.11\lib\dm-aggregates\adaptersフォルダの中にあるdata_objects_adapter.rbの46行目以下の
module SQL
private
alias original_property_to_column_name property_to_column_name
...
となっているところに、property_to_column_nameの定義を次のように追加するよ。
module SQL
private
def property_to_column_name(repository, property, qualify)
table_name = property.model.storage_name(repository.name) if property && property.respond_to?(:model)
if table_name && qualify
"#{quote_table_name(table_name)}.#{quote_column_name(property.field(repository.name))}"
else
quote_column_name(property.field(repository.name))
end
end
alias original_property_to_column_name property_to_column_name
...
開発用サーバの起動
次のコマンドを入力して、開発用サーバを起動してね。
> dev_appserver.cmd .
Webブラウザで開発用サーバにアクセス
http://localhost:8080/にアクセスして、動作確認してね。
Google App Engineにデプロイ
「appengine-web.xml」の「application」と「version」を適切に設定して、次のコマンドを実行してね。
> appcfg.cmd update .
2009-08-22
■ [Java][JRuby] Ramaze on GAE/J

Rubyで書かれた軽量Webアプリケーション開発フレームワーク「Ramaze」をGoogle App Engine for Java上でJRubyを使って動かすための、自分用のメモだよ。ここでの手順はWindowsで行うことを想定しているよ。
Java SDKのダウンロードとインストール
まだJava SDKをインストールしていない人は、ダウンロードしてインストールしてね。
Java SDKをインストールするには、Java SDKのダウンロードサイトにアクセスして、下のほうにある「JDK 6 Update 16」の右側の「Download」をクリックしてね。Platformは「Windows」を選択してね。
ダウンロードしたインストーラ「jdk-6u16-windows-i586.exe」をダブルクリックすると、インストールが始まるよ。
Google App Engine for Java SDKのダウンロードと展開
まだGoogle App Engine for Java SDKを入手していない人は、ダウンロードしてね。
Google App Engine for Java SDKを入手するには、Google App Engineのダウンロードサイトにアクセスして、「appengine-java-sdk-1.2.2.zip」をクリックしてダウンロードしてね。ダウンロードした「appengine-java-sdk-1.2.2.zip」ファイルは圧縮されているから、Cドライブ直下に展開してね。
ramaze_on_gaeディレクトリの作成
コマンドプロンプトを起動して、次のようにコマンドを入力してね
空白を含むパス上だとうまく動かないみたいなので、ここではCドライブ直下に作成しているよ
> cd \ > mkdir ramaze_on_gae > cd \ramaze_on_gae
jruby-complete-1.3.1.jarのダウンロードと設置
まだ「jruby-complete-1.3.1.jar」を入手していない人は、ダウンロードしてね。入手先はJRubyのダウンロードサイトだよ。
「jruby-complete-1.3.1.jar」をクリックしてダウンロードしたら、先ほど作ったC:\ramaze_on_gaeフォルダに配置してね。
WEB-INFフォルダの作成
先ほど作った「\ramaze_on_gae」ディレクトリの中に、次のように3つのディレクトリを作成するよ。
> mkdir WEB-INF > mkdir WEB-INF\gems > mkdir WEB-INF\lib
Ramazeのインストール
JRubyのgemコマンドを使って、必要となるライブラリを入手するよ。
> set JAVA_HOME=C:\PROGRA~1\Java\jdk1.6.0_16 > set PATH=%JAVA_HOME%\bin;C:\appengine-java-sdk-1.2.2\bin;%PATH% > java -jar jruby-complete-1.3.1.jar -S gem install -i WEB-INF\gems ramaze --no-ri --no-rdoc > del /q WEB-INF\gems\cache\*
jruby-core.jarとruby-stdlib.jarをlibフォルダに作成
次のようにコマンドを入力して、「jruby-complete-1.3.1.jar」から「jruby-core.jar」と「ruby-stdlib.jar」を作成するよ。ここでは元となる「jruby-complete-1.3.1.jar」は削除しているけど、削除したくない人は他のフォルダにコピーしておいてね。
> mkdir tmp_unpack > cd tmp_unpack > jar xf ../jruby-complete-1.3.1.jar > cd .. > mkdir jruby-core > move tmp_unpack\org jruby-core > move tmp_unpack\com jruby-core > move tmp_unpack\jline jruby-core > move tmp_unpack\jay jruby-core > move tmp_unpack\jruby jruby-core > cd jruby-core > jar cf ../jruby-core.jar . > cd ..\tmp_unpack > jar cf ../ruby-stdlib.jar . > cd .. > rmdir /s /q jruby-core > rmdir /s /q tmp_unpack > move jruby-core.jar WEB-INF\lib > move ruby-stdlib.jar WEB-INF\lib > del jruby-complete-1.3.1.jar
appengine-api-1.0-sdk-1.2.2.jarのコピー
次のコマンドを入力して、「appengine-api-1.0-sdk-1.2.2.jar」ファイルをコピーするよ。
> copy C:\appengine-java-sdk-1.2.2\lib\user\appengine-api-1.0-sdk-1.2.2.jar WEB-INF\lib
jruby-rack-0.9.5-SNAPSHOT.jarのダウンロードと配置
こちらのサイトから「jruby-rack-0.9.5-SNAPSHOT.jar」をダウンロードして、C:\ramaze_on_gae\WEB-INF\libに配置してね。ダウンロードは右下のほうの「raw」というリンクをクリックしてね。
WEB-INF/hello.rbの作成
テキストエディタで次の内容を入力して、WEB-INFフォルダの中にhello.rbという名前で保存してね。単に「Hello, World!!」と表示させるだけのアプリケーションだよ。
require 'rubygems'
require 'ramaze'
class MainController < Ramaze::Controller
def index
"Hello, World!"
end
end
WEB-INF/appengine-web.xmlの作成
テキストエディタで次の内容を入力して、WEB-INFフォルダの中にappengine-web.xmlという名前で保存してね。
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>ramaze_on_gae</application>
<version>1</version>
<static-files />
<resource-files />
<sessions-enabled>false</sessions-enabled>
<system-properties>
<property name="jruby.management.enabled" value="false" />
<property name="os.arch" value="" />
<property name="jruby.compile.mode" value="JIT"/> <!-- JIT|FORCE|OFF -->
<property name="jruby.compile.fastest" value="true"/>
<property name="jruby.compile.frameless" value="true"/>
<property name="jruby.compile.positionless" value="true"/>
<property name="jruby.compile.threadless" value="false"/>
<property name="jruby.compile.fastops" value="false"/>
<property name="jruby.compile.fastcase" value="false"/>
<property name="jruby.compile.chainsize" value="500"/>
<property name="jruby.compile.lazyHandles" value="false"/>
<property name="jruby.compile.peephole" value="true"/>
</system-properties>
</appengine-web-app>
WEB-INF/web.xmlの作成
テキストエディタで次の内容を入力して、WEB-INFフォルダの中にweb.xmlという名前で保存してね。
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<context-param>
<param-name>public.root</param-name>
<param-value>/</param-value>
</context-param>
<context-param>
<param-name>rackup</param-name>
<param-value>require 'rubygems'
class Thread
def Thread.exclusive
_old = Thread.critical
begin
Thread.critical = true
return yield
ensure
Thread.critical = _old
end
end
end
require 'ramaze'
require 'hello'
Ramaze.start(:root => __DIR__, :started => true)
run Ramaze
</param-value>
</context-param>
<context-param>
<param-name>jruby.min.runtimes</param-name>
<param-value>1</param-value>
</context-param>
<context-param>
<param-name>jruby.max.runtimes</param-name>
<param-value>1</param-value>
</context-param>
<context-param>
<param-name>jruby.init.serial</param-name>
<param-value>true</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>
開発用サーバの起動
次のコマンドを入力して、開発用サーバを起動してね。
> dev_appserver.cmd .
Webブラウザで開発用サーバにアクセス
http://localhost:8080/にアクセスして、動作確認してね。
Google App Engineにデプロイ
「appengine-web.xml」の「application」と「version」を適切に設定して、次のコマンドを実行してね。
> appcfg.cmd update .
2009-08-15
■ [Java][JRuby][Sinatra] SinatBBS on GAE/J

「Ruby Freaks Lounge:第9回 SinatraとSequel・Hamlで掲示板アプリを作る|gihyo.jp … 技術評論社」という記事にある「SinatBBS」という掲示板アプリを、Google App Engine for Java上でJRubyを使って動かすための、自分用のメモだよ。
ここでの手順は、Windowsで行うことを想定しているよ。
Java SDKのダウンロードとインストール
まだJava SDKをインストールしていない人は、ダウンロードしてインストールしてね。
Java SDKをインストールするには、Java SDKのダウンロードサイトにアクセスして、下のほうにある「JDK 6 Update 16」の右側の「Download」をクリックしてね。Platformは「Windows」を選択してね。
ダウンロードしたインストーラ「jdk-6u16-windows-i586.exe」をダブルクリックすると、インストールが始まるよ。
Google App Engine for Java SDKのダウンロードと展開
まだGoogle App Engine for Java SDKを入手していない人は、ダウンロードしてね。
Google App Engine for Java SDKを入手するには、Google App Engineのダウンロードサイトにアクセスして、「appengine-java-sdk-1.2.2.zip」をクリックしてダウンロードしてね。ダウンロードした「appengine-java-sdk-1.2.2.zip」ファイルは圧縮されているから、Cドライブ直下に展開してね。
sinatbbsディレクトリの作成
コマンドプロンプトを起動して、次のようにコマンドを入力してね
空白を含むパス上だとうまく動かないみたいなので、ここではCドライブ直下に作成しているよ
> cd \ > mkdir sinatbbs > cd \sinatbbs
jruby-complete-1.3.1.jarのダウンロードと設置
まだ「jruby-complete-1.3.1.jar」を入手していない人は、ダウンロードしてね。入手先はJRubyのサイトだよ。
「jruby-complete-1.3.1.jar」をクリックしてダウンロードしたら、先ほど作ったC:\sinatbbsフォルダに配置してね。
WEB-INFフォルダの作成
先ほど作った「sinatbbs」ディレクトリの中に、次のように3つのディレクトリを作成するよ。
> mkdir WEB-INF > mkdir WEB-INF\gems > mkdir WEB-INF\lib
Sinatra、DataMapper、Hamlのインストール
JRubyのgemコマンドを使って、必要となるライブラリを入手するよ。
> set JAVA_HOME=C:\PROGRA~1\Java\jdk1.6.0_16 > set PATH=%JAVA_HOME%\bin;C:\appengine-java-sdk-1.2.2\bin;%PATH% > java -jar jruby-complete-1.3.1.jar -S gem install -i WEB-INF\gems sinatra --no-ri --no-rdoc > java -jar jruby-complete-1.3.1.jar -S gem install -i WEB-INF\gems addressable --no-ri --no-rdoc > java -jar jruby-complete-1.3.1.jar -S gem install -i WEB-INF\gems dm-datastore-adapter --no-ri --no-rdoc > java -jar jruby-complete-1.3.1.jar -S gem install -i WEB-INF\gems haml --no-ri --no-rdoc > rmdir /s /q WEB-INF\gems\bin > del /q WEB-INF\gems\cache\*
jruby-core.jarとruby-stdlib.jarをlibフォルダに作成
次のようにコマンドを入力して、「jruby-complete-1.3.1.jar」から「jruby-core.jar」と「ruby-stdlib.jar」を作成するよ。ここでは元となる「jruby-complete-1.3.1.jar」は削除しているけど、削除したくない人は他のフォルダにコピーしておいてね。
> mkdir tmp_unpack > cd tmp_unpack > jar xf ../jruby-complete-1.3.1.jar > cd .. > mkdir jruby-core > move tmp_unpack\org jruby-core > move tmp_unpack\com jruby-core > move tmp_unpack\jline jruby-core > move tmp_unpack\jay jruby-core > move tmp_unpack\jruby jruby-core > cd jruby-core > jar cf ../jruby-core.jar . > cd ..\tmp_unpack > jar cf ../ruby-stdlib.jar . > cd .. > rmdir /s /q jruby-core > rmdir /s /q tmp_unpack > move jruby-core.jar WEB-INF\lib > move ruby-stdlib.jar WEB-INF\lib > del jruby-complete-1.3.1.jar
appengine-api-1.0-sdk-1.2.2.jarのコピー
次のコマンドを入力して、「appengine-api-1.0-sdk-1.2.2.jar」ファイルをコピーするよ。
> copy C:\appengine-java-sdk-1.2.2\lib\user\appengine-api-1.0-sdk-1.2.2.jar WEB-INF\lib
jruby-rack-0.9.4.jarのダウンロードと配置
JRuby-Rackのサイトから「jruby-rack-0.9.4.jar」をダウンロードして、C:\sinatra_on_gae\WEB-INF\libに配置してね。
WEB-INF/start.rbの作成
テキストエディタで次の内容を入力して、WEB-INFフォルダの中にstart.rbという名前で保存してね。
require 'rubygems' require 'sinatra' require 'model/comment.rb' helpers do include Rack::Utils; alias_method :h, :escape_html end get '/style.css' do content_type 'text/css', :charset => 'utf-8' sass :style end get '/' do @comments = Comments.all(:order => [:posted_date.desc]) haml :index end put '/comment' do Comments.create( :name => request[:name], :title => request[:title], :message => request[:message], :posted_date => Time.now ) redirect '/' end
WEB-INF/model/comment.rbの作成
テキストエディタで次の内容を入力して、WEB-INFフォルダの中にmodelフォルダを作成して、そこにcomment.rbという名前で保存してね。
require 'dm-core'
require 'dm-aggregates'
require 'dm-types'
require 'dm-datastore-adapter/datastore-adapter'
DataMapper.setup(:datastore,
:adapter => :datastore,
:database => 'comments')
class Comments
include DataMapper::Resource
def self.default_repository_name; :datastore end
property :id, Serial
property :name, String
property :title, String
property :message, Text, :lazy => false
property :posted_date, DateTime
def date
(self.posted_date.new_offset(Rational(3, 8))).strftime("%Y-%m-%d %H:%M:%S")
end
def formatted_message
Rack::Utils.escape_html(self.message).gsub(/\n/, "<br>")
end
end
WEB-INF/views/index.hamlの作成
テキストエディタで次の内容を入力して、WEB-INFフォルダの中にviewsフォルダを作成して、そこにindex.hamlという名前で保存してね。あ、このファイルは日本語を含んでいるから、ファイルを保存するときは文字コードを「UTF-8」に設定してね。
%form{:method => "POST", :action => '/comment'}
%input{:type => "hidden", :name => "_method", :value => "PUT"}
%table
%tr
%td 名前
%td
%input{:type => "text", :name => "name"}
%tr
%td タイトル
%td
%input{:type => "text", :name => "title"}
%tr
%td 内容
%td
%textarea{:name => "message", :cols => 60, :rows => 8}
%tr
%td
%td
%input{:type => "submit"}
- @comments.each do |comment|
.comment
%h2= h comment.title
.info
%span.name== by #{h comment.name}
%span.date== (#{h comment.date})
.message
= comment.formatted_message
WEB-INF/views/layout.hamlの作成
テキストエディタで次の内容を入力して、WEB-INFフォルダの中のviewsフォルダの中にlayout.hamlという名前で保存してね。
!!! XML
!!! Strict
%html
%head
%title SinatBBS
%meta{:"http-equiv"=>"Content-Type", :content=>"text/html", :charset=>"utf-8"}
%link{:rel=>"stylesheet", :type=>"text/css", :href=>"/style.css"}
%body
%h1 SinatBBS
!= yield
WEB-INF/views/style.sassの作成
テキストエディタで次の内容を入力して、WEB-INFフォルダの中にviewsフォルダの中にstyle.sassという名前で保存してね。
body
margin: 0px 20%
padding: 0px
h1
margin: 1em
form
border: 1px solid black
margin: 1em
padding: 0.5em
.comment
border: 1px solid black
margin: 1em
padding: 0.5em
h2
margin: 0px
font-size: medium
float: left
.info
span.name
padding-left: 0.5em
font-size: small
span.date
font-size: small
.message
margin-top: 1em
WEB-INF/appengine-web.xmlの作成
テキストエディタで次の内容を入力して、WEB-INFフォルダの中にappengine-web.xmlという名前で保存してね。
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>sinatra_on_gae</application>
<version>1</version>
<static-files />
<resource-files />
<sessions-enabled>false</sessions-enabled>
<system-properties>
<property name="jruby.management.enabled" value="false" />
<property name="os.arch" value="" />
<property name="jruby.compile.mode" value="JIT"/> <!-- JIT|FORCE|OFF -->
<property name="jruby.compile.fastest" value="true"/>
<property name="jruby.compile.frameless" value="true"/>
<property name="jruby.compile.positionless" value="true"/>
<property name="jruby.compile.threadless" value="false"/>
<property name="jruby.compile.fastops" value="false"/>
<property name="jruby.compile.fastcase" value="false"/>
<property name="jruby.compile.chainsize" value="500"/>
<property name="jruby.compile.lazyHandles" value="false"/>
<property name="jruby.compile.peephole" value="true"/>
</system-properties>
</appengine-web-app>
WEB-INF/web.xmlの作成
テキストエディタで次の内容を入力して、WEB-INFフォルダの中にweb.xmlという名前で保存してね。
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<context-param>
<param-name>public.root</param-name>
<param-value>/</param-value>
</context-param>
<context-param>
<param-name>rackup</param-name>
<param-value>require 'rubygems'
require 'sinatra'
root_dir = File.dirname(__FILE__)
#set :environment, :production
set :environment, :development
set :root, root_dir
set :app_file, File.join(root_dir, 'start.rb')
disable :run
require 'start'
run Sinatra::Application
</param-value>
</context-param>
<context-param>
<param-name>jruby.min.runtimes</param-name>
<param-value>1</param-value>
</context-param>
<context-param>
<param-name>jruby.max.runtimes</param-name>
<param-value>1</param-value>
</context-param>
<context-param>
<param-name>jruby.init.serial</param-name>
<param-value>true</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>
開発用サーバの起動
次のコマンドを入力して、開発用サーバを起動してね。
> dev_appserver.cmd .
Webブラウザで開発用サーバにアクセス
http://localhost:8080/にアクセスして、動作確認してね。
Google App Engineにデプロイ
「appengine-web.xml」の「application」と「version」を適切に設定して、次のコマンドを実行してね。
> appcfg.cmd update .
2009-08-12
■ [Java][JRuby] jruby-complete-1.3.1.jarからjruby-core.jarとruby-stdlib.jarを作る

Windowsでjruby-complete-1.3.1.jarからjruby-core.jarとruby-stdlib.jarを作るための、自分用のメモだよ。基本的にはd:id:technohippyさんのこちらのエントリの通りだよ。
ちなみに、jruby-core.jarとruby-stdlib.jarは、Google App Engine上でJRubyを使うために必要となるファイルだよ。詳しい使い方は、また今度。
- Java SDKのダウンロードとインストール
- jruby-complete-1.3.1.jarのダウンロード
- http://dist.codehaus.org/jruby/1.3.1/
- 「jruby-complete-1.3.1.jar」をクリックしてダウンロードしてね
- コマンドプロンプトの起動
- コマンドプロンプトを起動して、次のようにコマンドを入力してね
> set JAVA_HOME=C:\PROGRA~1\Java\jdk1.6.0_16 > set PATH=%JAVA_HOME%\bin;%PATH% > cd [jruby-complete-1.3.1.jarをダウンロードしたディレクトリ] > mkdir tmp_unpack > cd tmp_unpack > jar xf ../jruby-complete-1.3.1.jar > cd .. > mkdir jruby-core > move tmp_unpack\org jruby-core > move tmp_unpack\com jruby-core > move tmp_unpack\jline jruby-core > move tmp_unpack\jay jruby-core > move tmp_unpack\jruby jruby-core > cd jruby-core > jar cf ../jruby-core.jar . > cd ..\tmp_unpack > jar cf ../ruby-stdlib.jar . > cd .. > rmdir /s /q jruby-core > rmdir /s /q tmp_unpack
これで、「jruby-complete-1.3.1.jar」と同じフォルダに「jruby-core.jar」と「ruby-stdlib.jar」ができているはずだよ。
■ [Java][JRuby] 「jruby-complete-1.3.1.jar」はJRuby一式

説明を省略しちゃったけど、「jruby-complete-1.3.1.jar」はJRubyを動かすために必要なライブラリを全部含んだものだよ。だから、Javaの実行環境と「jruby-complete-1.3.1.jar」さえあれば、JRubyをインストールしていなくても次のような感じでJRubyを起動することができるよ。
> java -jar jruby-complete-1.3.1.jar -v jruby 1.3.1 (ruby 1.8.6p287) (2009-06-15 6586) (Java HotSpot(TM) Client VM 1.6.0_16) [x86-java] > java -jar jruby-complete-1.3.1.jar -S jirb irb(main):001:0> 2 + 3 5 irb(main):002:0> exit >
気軽にRubyを試してみたい、という人にもいいかも!
■ [Java][JRuby] Sinatra on GAE/J

Rubyで書かれた軽量Webアプリケーション開発フレームワーク「Sinatra」をGoogle App Engine for Java上でJRubyを使って動かすための、自分用のメモだよ。基本的にはjugyoさんのこちらのエントリの通りだよ。ここでの手順はWindowsで行うことを想定しているよ。
- Google App Engine for Java SDKのダウンロードと展開
- http://code.google.com/p/googleappengine/downloads/list
- 「appengine-java-sdk-1.2.2.zip」をダウンロードして、Cドライブ直下に展開してね
- sinatra_on_gaeディレクトリの作成
- コマンドプロンプトを起動して、次のようにコマンドを入力してね
- 空白を含むパス上だとうまく動かないみたいなので、ここではCドライブ直下に作成しているよ
> cd \ > mkdir sinatra_on_gae
- jruby-complete-1.3.1.jarの設置
- http://dist.codehaus.org/jruby/1.3.1/
- 「jruby-complete-1.3.1.jar」をクリックしてダウンロードして、C:\sinatra_on_gaeフォルダに配置してね
- アプリケーションのフォルダの作成
> cd \sinatra_on_gae > mkdir WEB-INF > mkdir WEB-INF\gems > mkdir WEB-INF\lib
- Sinatraのインストール
> set JAVA_HOME=C:\PROGRA~1\Java\jdk1.6.0_16 > set PATH=%JAVA_HOME%\bin;C:\appengine-java-sdk-1.2.2\bin;%PATH% > java -jar jruby-complete-1.3.1.jar -S gem install -i WEB-INF\gems sinatra --no-ri --no-rdoc > rmdir /s /q WEB-INF\gems\bin > del /q WEB-INF\gems\cache\*
> mkdir tmp_unpack > cd tmp_unpack > jar xf ../jruby-complete-1.3.1.jar > cd .. > mkdir jruby-core > move tmp_unpack\org jruby-core > move tmp_unpack\com jruby-core > move tmp_unpack\jline jruby-core > move tmp_unpack\jay jruby-core > move tmp_unpack\jruby jruby-core > cd jruby-core > jar cf ../jruby-core.jar . > cd ..\tmp_unpack > jar cf ../ruby-stdlib.jar . > cd .. > rmdir /s /q jruby-core > rmdir /s /q tmp_unpack > move jruby-core.jar WEB-INF\lib > move ruby-stdlib.jar WEB-INF\lib > del jruby-complete-1.3.1.jar
> copy C:\appengine-java-sdk-1.2.2\lib\user\appengine-api-1.0-sdk-1.2.2.jar WEB-INF\lib
- jruby-rack-0.9.4.jarのダウンロードと配置
- http://kenai.com/projects/jruby-rack/pages/Home
- 「jruby-rack-0.9.4.jar」をダウンロードして、C:\sinatra_on_gae\WEB-INF\libに配置してね
- WEB-INF/app.rbの作成
- 単に「Hello World!!」と表示させるだけのアプリケーションだよ。
require 'rubygems' require 'sinatra' get '/' do 'Hello World!!' end
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>sinatra_on_gae</application>
<version>1</version>
<static-files />
<resource-files />
<sessions-enabled>false</sessions-enabled>
<system-properties>
<property name="jruby.management.enabled" value="false" />
<property name="os.arch" value="" />
<property name="jruby.compile.mode" value="JIT"/> <!-- JIT|FORCE|OFF -->
<property name="jruby.compile.fastest" value="true"/>
<property name="jruby.compile.frameless" value="true"/>
<property name="jruby.compile.positionless" value="true"/>
<property name="jruby.compile.threadless" value="false"/>
<property name="jruby.compile.fastops" value="false"/>
<property name="jruby.compile.fastcase" value="false"/>
<property name="jruby.compile.chainsize" value="500"/>
<property name="jruby.compile.lazyHandles" value="false"/>
<property name="jruby.compile.peephole" value="true"/>
</system-properties>
</appengine-web-app>
- WEB-INF/web.xmlの作成
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<context-param>
<param-name>public.root</param-name>
<param-value>/</param-value>
</context-param>
<context-param>
<param-name>rackup</param-name>
<param-value>require 'rubygems'
require 'sinatra'
root_dir = File.dirname(__FILE__)
#set :environment, :production
set :environment, :development
set :root, root_dir
set :app_file, File.join(root_dir, 'app.rb')
disable :run
require 'app'
run Sinatra::Application
</param-value>
</context-param>
<context-param>
<param-name>jruby.min.runtimes</param-name>
<param-value>1</param-value>
</context-param>
<context-param>
<param-name>jruby.max.runtimes</param-name>
<param-value>1</param-value>
</context-param>
<context-param>
<param-name>jruby.init.serial</param-name>
<param-value>true</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>
- 開発用サーバの起動
> dev_appserver.cmd .
- Webブラウザで開発用サーバにアクセス
> appcfg.cmd update .