0. Abstract
熱海はハードル高いので、まずは自宅だよね。ということで、ちょっと以前から:
GoogleAppEngine + JRubyでクリスマスまでに彼女をつくる方法
[Ruby][クラウド] GAE/JRuby/SinatraでHello World
appengine-jrubyで簡単GAE/JRuby開発
JRuby on Rails を GAE/J 上へデプロイ
- 10分ではじめる GAE/JRuby (OAuth + Sinatraのサンプル)
- Impossible to do POSTs with appengine-jruby/RoR: Reflection is not allowed
などを参照して、ローカルPC(XP)でGAEの実験してたわけだが、これまで当方の環境では、ThreadErrorを吐くなど不具合があり、寸分も動作しなかった。
この度、やっと動作を確認できたので、ここに試行錯誤をまとめて示そうと思う。
結論だけ先に挙げますと、gemパッケージ内の主にJRubyに何らかの原因がありいくつか不具合現象が生じていたが、gemの更新により、それらが解消された、というつまらないことなのですが…。
それに加えて、今回ちょっと特殊なのは:
- XPのアカウント名が日本語だったこと
- 動作確認にCygwinも用いたこと
になります。
上記に起因する不具合現象について、相当調査し(ぐぐっ)たが、エラーそのものも含めて、全然情報がなかった。ActiveScriptRubyやCygwinという当方とまっ
たく同じ環境でも、何の問題も無く、みんなすんなり動いてるようでした。
本稿ではまず、1.に実験した環境・構成を示します。次に2.にて、当初存在した
不具合現象を示します。そして、3.に今回成功した修正方法を、4.に修正後の動作結果を示します。最後に、修正方法を5.結論に述べ、今後の課題を6.とします。
またリファレンスと付録を、それぞれ7.、8.とします。
1.動作確認に使用した環境と構成
以下、(1)~(2)に、環境・構成等を示す。
Windows XPは、以下XPと略す。
Cygwin/XPは、XP上にインストールしたCygwinを示す。
ActiveScriptRubyでの実験は、同環境をインストールするとできるruby console
から行った。
Cygwin/XPでの実験は、Cygwinのコンソールから行った。
(1) 実験した環境
実験していたのは、下記のような環境である:
OS Windows XP(winver.exe; Version 5.1 (Build 2600.xpsp_sp3_gdr .100216-1514 :Service Pack 3)), Cygwin/XP(setup.exe version 2.697) Ruby ActiveScriptRuby 1.8.7 (XP; ruby 1.8.7 (2010-01-10 patchlevel 249) [i386-mswin32]), Ruby 1.8.7 (Cygwin/XP; ruby 1.8.7 (2008-08-11 patchlevel 72) [i386-cygwin]) Java java version "1.6.0_20" Java(TM) SE Runtime Environment (build 1.6.0_20-b02) Java HotSpot(TM) Client VM (build 16.3-b01, mixed mode)
AcriveScriptRuby、Cygwin/XP上のruby両者で、動作することを確認できた。
(2)gemの構成
- 構成1(動作しない)
$ gem list *** LOCAL GEMS *** appengine-apis (0.0.16) appengine-rack (0.0.9) appengine-sdk (1.3.4) appengine-tools (0.0.13) bundler08 (0.8.5) google-appengine (0.0.13) jruby-jars (1.4.1) jruby-rack (1.0.1) rack (1.1.0) rubygems-update (1.3.7) rubyzip (0.9.4)
$ gem list *** LOCAL GEMS *** appengine-apis (0.0.18, 0.0.16) appengine-rack (0.0.11, 0.0.9) appengine-sdk (1.3.5, 1.3.4) appengine-tools (0.0.15, 0.0.13) bundler08 (0.8.5) google-appengine (0.0.15, 0.0.13) jruby-jars (1.5.1, 1.4.1) jruby-rack (1.0.1) rack (1.1.0) rubygems-update (1.3.7) rubyzip (0.9.4)
2.不具合現象
不具合現象は、実行時に下記ログに示されるような現象である(一部、当方で入れた
デバッグ用のメッセージも含む)。
◇ログ1(ActiveScriptRuby; No such file or directory (Errno::ENOENT))
D:\Program Files\ruby-1.8\usr\local\sinatra_test>appcfg.rb bundle . D:/Program Files/ruby-1.8/lib/ruby/gems/1.8/gems/appengine-tools-0.0.13/lib/appe ngine-tools/boot.rb:78: warning: `*' interpreted as argument prefix file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/jruby-stdlib -1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems.rb:926:in `set_pa ths': No such file or directory - No such file or directory - C:/Documents and S ettings/テ」ツ・セテ」ツ・・(Errno::ENOENT) from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems.rb from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems.rb from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems/defa ults/jruby.rb:17:in `set_paths' from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems.rb from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems/defa ults/jruby.rb:60:in `installed_spec_directories' from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems/sour ce_index.rb:58:in `from_installed_gems' from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems.rb from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems/gem_ path_searcher.rb:84:in `init_gemspecs' from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems/gem_ path_searcher.rb:19:in `initialize' from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems.rb from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems.rb from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems.rb from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems.rb from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems.rb from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems.rb from D:/PROGRA~1/ruby-1.8/bin/appcfg.rb:9 Error executing jruby
◇エラーログ2 (Cygwin/XP, dev_appserver.rb; Error opening zip file or JAR manifest missing)
$dev_appserver.rb . /usr/lib/ruby/gems/1.8/gems/appengine-tools-0.0.15/lib/appengine-tools/boot.rb => Booting DevAppServer => Press Ctrl-C to shutdown server exec "java" "-classpath" "/usr/lib/ruby/gems/1.8/gems/appengine-sdk-1.3.5/appeng ine-java-sdk-1.3.5/lib/appengine-tools-api.jar" "-Djava.util.logging.config.file =/usr/lib/ruby/gems/1.8/gems/appengine-sdk-1.3.5/appengine-java-sdk-1.3.5/config /sdk/logging.properties" "-Dcom.google.appengine.plugin.path=/usr/lib/ruby/gems/1 .8/gems/appengine-tools-0.0.15/lib/appengine-tools/app_yaml.jar" "-javaagent:/u sr/lib/ruby/gems/1.8/gems/appengine-sdk-1.3.5/appengine-java-sdk-1.3.5/lib/agent /appengine-agent.jar" "com.google.appengine.tools.development.DevAppServerMain" "--disable_update_check" "/home/masa/local/sinatra_test" Error opening zip file or JAR manifest missing : /usr/lib/ruby/gems/1.8/gems/app engine-sdk-1.3.5/appengine-java-sdk-1.3.5/lib/agent/appengine-agent.jar Error occurred during initialization of VM agent library failed to init: instrument
◇エラーログ3(ActiveScriptRuby; Mutex relocking by same thread (ThreadError))
D:\Program Files\ruby-1.8\usr\local\sinatra_test>appcfg.rb generate_app . D:/Program Files/ruby-1.8/lib/ruby/gems/1.8/gems/appengine-tools-0.0.13/lib/appe ngine-tools/boot.rb:78: warning: `*' interpreted as argument prefix => Generating gemfile => Bundling gems D:/Program Files/ruby-1.8/lib/ruby/1.8/pathname.rb:263: warning: `*' interpreted as argument prefix D:/Program Files/ruby-1.8/lib/ruby/gems/1.8/gems/bundler08-0.8.5/lib/bundler08/d ependency.rb:59: warning: discarding old version Calculating dependencies... Updating source: http://gems.rubyforge.org D:/Program Files/ruby-1.8/lib/ruby/gems/1.8/gems/bundler08-0.8.5/lib/bundler08/r esolver.rb:115:Warning: Gem::Dependency#version_requirements is deprecated and w ill be removed on or after August 2010. Use #requirement Caching: appengine-rack-0.0.9.gem Caching: jruby-jars-1.4.1.gem Caching: jruby-rack-1.0.1.gem Caching: rack-1.1.0.gem Installing jruby-jars (1.4.1) Installing rack (1.1.0) Installing jruby-rack (1.0.1) Installing appengine-rack (0.0.9) Done. => Packaging gems => Installing appengine-rack.jar => Installing jruby-core-1.4.1.jar => Installing jruby-stdlib-1.4.1.jar => Installing jruby-rack-1.0.1.jar => Installing appengine-sdk => Generating rackup file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/jruby-stdlib -1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems.rb:888:in `search er': Mutex relocking by same thread (ThreadError) from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems/cust om_require.rb:33:in `require' from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/shared/builtin/ja vasupport.rb:37 from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/shared/builtin/ja vasupport.rb:31:in `require' from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems/cust om_require.rb:31:in `require' from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems/defa ults/jruby.rb:70:in `spec_directories_from_classpath' from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems/defa ults/jruby.rb:60:in `installed_spec_directories' from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems/sour ce_index.rb:58:in `from_installed_gems' from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems.rb from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems/gem_ path_searcher.rb:84:in `init_gemspecs' from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems/gem_ path_searcher.rb:19:in `initialize' from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems.rb from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems.rb from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems.rb from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems.rb from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems.rb from file:/D:/Program Files/ruby-1.8/usr/local/sinatra_test/WEB-INF/lib/ jruby-stdlib-1.4.1.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems.rb:9 from D:/PROGRA~1/ruby-1.8/bin/appcfg.rb:9 Error executing jruby
3.回避・修正方法
不具合現象の(1)、(3)に関しては、google-appengineパッケージの更新(下記(1))で、修正されることがわかった。不具合現象(2)については、パッケージ内のスクリプトの一部のパスの指定方法に、問題があることがわかった(下記(2))。
下記(1)、(2)に回避・修正方法を示す。
(1) GAE gemファイルの更新
エラーログから、jruby-jar等に問題があることが推測された。
google-appengineのgemを最新のものに更新することで、当該現象は発生が抑えられた。
gem update google-appengine
(2) GAE/JRubyのスクリプトdev_appserver.rbの修正(Cygwinの場合)
パスの指定部分を、全てcygpathでラッピングする[1]。
/lib/ruby/gems/1.8/gems/appengine-tools-0.0.15/lib/appengine-tools/ appserver.rb < server_args[-1] = File.expand_path(path) --- > tmp_expath = File.expand_path(path) > server_args[-1] = `cygpath -wp #{tmp_expath}`.chomp < java_args << AppEngine::SDK::TOOLS_JAR --- > java_args << `cygpath -wp #{AppEngine::SDK::TOOLS_JAR}`.chomp < AppEngine::SDK::SDK_ROOT + '/config/sdk/logging.properties' < java_args << "-Dcom.google.appengine.plugin.path=#{plugin_jar}" --- > `cygpath -wp #{AppEngine::SDK::SDK_ROOT}/config/sdk/logging.prop erties`.chomp > java_args << "-Dcom.google.appengine.plugin.path="+`cygpath -wp #{pl ugin_jar}`.chomp > < java_args << '-javaagent:' + AppEngine::SDK::AGENT_JAR --- > java_args << '-javaagent:' + `cygpath -wp #{AppEngine::SDK::AGENT_ JAR}`.chomp
これもっと綺麗な方法ないかな、とも思いますが・・・。
4.動作結果
ブラウザからhttp://localhost:8080/にアクセスすれば、所望の結果が得られる。
D:\Program Files\ruby-1.8\usr\local\sinatra_test>dev_appserver.rb.bat . D:/PROGRA~1/ruby-1.8/lib/ruby/gems/1.8/gems/appengine-tools-0.0.15/lib/appengine -tools/boot.rb:50: warning: `*' interpreted as argument prefix => Booting DevAppServer => Press Ctrl-C to shutdown server 2010/07/26 1:23:22 com.google.apphosting.utils.jetty.JettyLogger info 情報: Logging to JettyLogger(null) via com.google.apphosting.utils.jetty.JettyLo gger 2010/07/26 1:23:22 com.google.apphosting.utils.config.AppEngineWebXmlReader read AppEngineWebXml 情報: Successfully processed D:\Program Files\ruby-1.8\usr\local\sinatra_test\WE B-INF/appengine-web.xml 2010/07/26 1:23:22 com.google.apphosting.utils.config.AbstractConfigXmlReader re adConfigXml 情報: Successfully processed D:\Program Files\ruby-1.8\usr\local\sinatra_test\WE B-INF/web.xml 2010/07/26 1:23:22 com.google.apphosting.utils.jetty.JettyLogger info 情報: jetty-6.1.x 2010/07/26 1:23:25 com.google.apphosting.utils.jetty.JettyLogger info 情報: Started SelectChannelConnector@127.0.0.1:8080 2010/07/26 1:23:25 com.google.appengine.tools.development.DevAppServerImpl start 情報: The server is running at http://localhost:8080/
5.結論
JRuby(jruby-jars)は、バージョンによってはActiveScriptRuby、もしくはCygwin/XPにおいて、ThreadErrorにより動作しない
Cygwinでは、一部のスクリプトのjavaコマンド発行時のパス名が問題となる
上記により、ActiveScriptRuby, Cygwin/XP両者の環境で、ローカルPC上で、GAE/JRubyの動作を確認できた。
gemパッケージ:google-appengineを、最新のバージョンに更新する。
Cygwinのコマンド:cygpath -wp で、ラッピングしてjavaコマンドに渡されるように、dev_appserver.rbを修正する。
6. Future Works
- gem, appcfg.rb, dev_appserver.rb の使い方詳細の調査
- リモート・サーバ上での動作
- 彼女を作る
- 不具合現象の原因となるgemパッケージの依存関係、ThreadErrorの生じる箇所
については、今回あきらめた。JRubyの内部動作に強い興味を持つ向きは、探ってみてもよいかもしれない。
7.補論
- Gemリポジトリ格納場所の再設定
不具合現象(1)の発生は、3.回避・修正方法の(1)により、抑えられる。しかし、類似の現象を未然に防止するため、Gemリポジトリの設定をしておいたほうがよいかもしれない。
本稿の場合、3.appcfg.rbから実行されるgemにおいて、リポジトリ処理に日本語パス名起因である不具合現象(1)が、当初存在していた。
gemは、動作時にリポジトリ・ファイルを作成する[2]。
AcitiveScriptRubyの場合、特に指定がなければ、リポジトリはディレクトリ:%HOME%となる。このパス名に、日本語が含まれている場合、google-appengineのバージョンによっては、不具合現象(1) の原因になる。
これを防ぐには、google-appengineパッケージの更新、もしくは環境変数GEM_HOMEを、適切に設定する。
設定方法は、
コンパネ>システム>詳細設定、またはコマンド・プロンプト で、環境変数:GEM_HOMEを、日本語を含まないパスに設定する
である。
Cygwinに関しては、ホーム・ディレクトリを、日本語パス名を含まないものに変更している。
8.References
[1] Toru Takahashi; "CygwinでJavaを快適に使う";http://www.02.246.ne.jp/~torutk/javaoncygwin/javaoncygwin.html
[2] docs.rubygems.org; "RubyGems User Guide | RubyGems Manuals";
3.2 Installing RubyGems in a User Directory,
http://docs.rubygems.org/read/chapter/3#page83