読者です 読者をやめる 読者になる 読者になる

JRuby on Rails on Google App Engineで文字化け -- つづき

Ruby サービス

前のエントリー は昨夜の事でした。


それから必死で検索したところ(^^;) appengine-apis の memcache.rb を読み込むと Datastore に格納する日本語が文字化けする - milk1000ccという記事が見つかりました。

これだ! と思いましたがその時点では GAE (Google App Engine)のことがよく解ってなかったので、

とりあえず datastore_types.rb の Datastore::ruby_to_java を直せば直ります。

がどこのあるのかが解りませんでした ^^; そこで Google App Engineのことを勉強しました。

GAEのストレージとRailsのモデル

普通のRuby on Railsでは下の図のように、モデルは対応するRDBのテーブルとActiveRecord という ORM(O/Rマッパー)を介してデータのやり取りを行います。


それに対しGAEではRDBは使えず、BigTableというスケラビリティーの高いKeyValueStoreがサポートされています。また、BigTableを扱う Datastore というライブラリー(Google App Engine SDK)が、PythonJava用にサポートされています。

さらに、appengine-jrubyという Ruby言語(JRuby処理系)用の Google App Engine API ラッパーが提供されています。これを使うと GAE を Ruby言語(JRuby処理系)で簡単に扱えます。
ただし、DatastoreはKeyValueStoreでありRDB+ActiveRecordとはかなり異なります。その差を少し埋めるものとして Ola Biniさんが作った Bumble があります。ActiveRecordに比べると機能は非常に低いですが、これを使うとRails(ActiveRecord)風なプログラミングが出来ます。以上をまとめると下の図のようになります。

日本語が通るようにするには

appengine-apis の memcache.rb を読み込むと Datastore に格納する日本語が文字化けする - milk1000cc に書かれていたコードをappengine-jrubyへのパッチとして config/initializers/datastore_patch.rb ファイルに書きました。

module AppEngine
  module Datastore
    def Datastore.ruby_to_java(value)  # :nodoc:
      if SPECIAL_RUBY_TYPES.include? value.class
        value.to_java
      else
        case value
        when Fixnum
          java.lang.Long.new(value)
        when Float
          java.lang.Double.new(value)
        when String
          #value.to_java_string
          java.lang.String.new(value) # Thanks http://d.hatena.ne.jp/milk1000cc/20090802/1249218370
        else
          value
        end
      end
    end
  end
end

これで、日本語も文字化けせずにDatastoreに格納されるようになりました。 milk1000ccさんありがとうございますm(__)m

GAEへのデプロイ

GAEにデプロイするには、
1. Google App Engine - Google Codeに登録し、アプリケーションIDを取得します。

2. アプリケーション名 = アプリケーションIDでないとデプロイできませんので appengine-web.xml に書かれている<application>〜</application>を書き換え warble を再実行した後 デプロイコマンド appcfg.sh を使いデプロイします。
途中でGoogleに登録した際のメールアドレス、パスワード を訪ねられます。

% /usr/local/appengine-java-sdk/bin/appcfg.sh update tmp/war
Reading application configuration data...
2009-08-03 16:18:51.517::INFO:  Logging to STDERR via org.mortbay.log.StdErrLog
Beginning server interaction for XXXXX..
0% Creating staging directory
5% Scanning for jsp files.
20% Scanning files on local disk.
25% Initiating update.
Email: YYYYYYYY@gmail.com       
Password for YYYYYYYY@gmail.com: 
28% Cloning 11 static files.
31% Cloning 110 application files.
33% Cloned 100 files.
40% Uploading 6 files.
52% Uploaded 1 files.
61% Uploaded 2 files.
68% Uploaded 3 files.
73% Uploaded 4 files.
77% Uploaded 5 files.
80% Uploaded 6 files.
90% Deploying new version.
95% Will check again in 1 seconds
98% Will check again in 2 seconds
99% Closing update: new version is ready to start serving.
99% Uploading index definitions.

Update completed successfully.
Success.
Cleaning up temporary files...

成功したら、 http://アプリケーションID.appspot.com/ をアクセスするとデプロイしたアプリが使えます。