fc2ブログ
ホーム

移転でーす

はてなダイアリーへ移転しまーす。

http://d.hatena.ne.jp/kuromoyo/

Android 様は日本語ファイル名でダウンロードできない御様子

ファイルをダウンロードさせる Web アプリケーションでの日本語ファイル名対応の雑記です。

続きを読む

Scientific Linux 6.1 導入

宅鯖に Hadoop を乗っけるためのノードを構築する必要があるのだが、いつまでも CentOS 5 系でいるのも何なので 6 系を… いやいや、それなら同じ RedHat 系列で最近活発な Scientific Linux 6 を入れてみませう。

実際使ってみると CentOS 6 と Scientific Linux 6 では SL の方が少しだけカーネルやライブラリのアップデートが速い程度の違いしかありませんので、Better CentOS として SL を選択す方が良いかも知れません。ここらへんは好みですね。

続きを読む

Windows で Rails3 の動作環境構築を諦める3つの理由

Windows 7 に Ruby 1.9.2 + Rails 3.1.1 動作環境を構築しようと迷い込んだ壮絶な修羅の道について、後人が同じ轍を踏まないように要点を記しておきます。

理由1. ネイティブライブラリ

兎に角ネイティブライブラリ周りは鬼門。

gem でインストールするライブラリには導入時にネイティブライブラリ (Windows で言う DLL のようなもの) をコンパイルするものがありますが、このビルド方法が Windows 未対応であることが多い。自前でやるにもコンパイラの種類、バージョンの違いに厳しかったり、欠落したライブラリが何であるかソースを読まなければ分からなかったり、リンク先の DLL を MinGW 用にエクスポートしなければいけなかったり、そもそも C のソースが Unix 環境前提で修正箇所が大量にあるなど、とにかく一度トラブルと調査にかなりの時間を浪費するし最終的に解決しない事も多い。

私の場合は mysql2 アダプタのコンパイルに三連休の丸 2 日を費やして諦めました (残り一日はこのエントリで消えました)。代替で mysql, ruby-mysql アダプタで回避しようとしても MySQL2 で定義されている定数などをオンコードで参照していたため無理でしたし、この問題が解決しても後にまだ therubyracer のコンパイルが控えています。

理由2. 32bit

メモリをふんだんに載せた開発マシンでも 32bit 版一択という状況。Ruby ランタイムは 64bit 対応しているが、追加ライブラリが 64bit 未対応などの状況に遭遇することも少なくない。Ruby ランタイムも 64bit 自体が枯れていないようで原因不明のエラーに何度か遭遇した (当方の環境の問題かもしれないが)。

理由3. 環境との相性の悪さ

バッチファイル (*.bat) やファイルセパレータ (\) などの環境の違い、空白入りディレクトリ名などの慣習が MSYS や make と相性が悪く地味に問題の原因になる。

対策

今は VMWare に CentOS を入れて歪ながらも平穏な生活を送っています。

対策1. Windows を使わない

Rails プラットフォームは Unix 系 OS を前提として開発されている (Windows は放置気味な) ことが 3.1 になってさらに強くなったように感じます。可能であれば開発端末には Linux か Mac OS X を使ったほうが無駄な事に時間を費やさずに済むでしょう :-P

対策2. 仮想環境で Linux を立てる

問題なのは Rails の実行環境のため開発環境は Windows のままでかまわないでしょう。Windows 上に VMWare や VirtualBox で Linux 環境を作り、プロジェクトのディレクトリごとを共有して環境を分離するという方法も取れます。会社から Windows マシンしか与えられていないのであればこれが一番現実的ですね。

対策3. JRuby を使用する

Unix 系はどうも… と言うのであれば JRuby on Rails で構築するのも一つの手かと思います。リンク先の記事の通り、こちらは特に問題もなく動作環境が構築できます。ただサーバの起動が遅かったりライブラリ構成やコードの挙動が違うなどの弊害があるかもしれません。

開発用の動作環境ではなくリリース環境が Windows に縛られているという場合には JRuby しか選択肢はないですね。

"Could not find a JavaScript runtime" と Rails 3.1 起動に失敗する件

表題のままなのですが、結論から言いますと SELinux DEATH! そうです、またこいつなんです。

Rails 3.1 から内部で CaffeeScript を使うようになったそうで実行時に JavaScript ランタイムが必要になりました。Gemfile に execjs と therubyracer を追加して bundle install を実行すれば必要なライブラリが入ります。入るはずですなんです。

torao@cumin$ vi Gemfile
# ...
gem 'execjs'
gem 'therubyracer'  # 追加

torao@cumin$ bundle install

しかしそれでも「JavaScript ランタイムが見つからない」と Rails を起動できないことがあります。というかできませんでした。

torao@cumin$ rails server -e development
/home/torao/.rvm/gems/ruby-1.9.2-p290/gems/execjs-1.2.9/lib/execjs/runtimes.rb:47:in `autodetect': Could not find a JavaScript runtime. See https://github.com/sstephenson/execjs for a list of available runtimes. (ExecJS::RuntimeUnavailable)
        from /home/torao/.rvm/gems/ruby-1.9.2-p290/gems/execjs-1.2.9/lib/execjs.rb:5:in `'
        from /home/torao/.rvm/gems/ruby-1.9.2-p290/gems/execjs-1.2.9/lib/execjs.rb:4:in `'
…

gem list を実行しても必要な JavaScript ランタイムが導入されているように見えます。

torao@cumin$  gem list

*** LOCAL GEMS ***

actionmailer (3.1.1)
…
execjs (1.2.9)
…
therubyracer (0.9.8)
…

Rails から見えていないというより Ruby 実行環境から見えていないのかも? コマンドラインから直接 require で参照してみましたが同じエラーが出るため Ruby からライブラリが見えていないようです。

torao@cumin$ ruby -e "require 'execjs'"
/home/torao/.rvm/gems/ruby-1.9.2-p290/gems/execjs-1.2.9/lib/execjs/runtimes.rb:47:in `autodetect': Could not find a JavaScript runtime. See https://github.com/sstephenson/execjs for a list of available runtimes. (ExecJS::RuntimeUnavailable)
        from /home/torao/.rvm/gems/ruby-1.9.2-p290/gems/execjs-1.2.9/lib/execjs.rb:5:in `'
        from /home/torao/.rvm/gems/ruby-1.9.2-p290/gems/execjs-1.2.9/lib/execjs.rb:4:in `'
        from :33:in `require'
        from :33:in `rescue in require'
        from :29:in `require'
        from -e:1:in `
'

例外の発生箇所 execjs/runtimes.rb(47) を見てみます。環境変数 EXECJS_RUNTIME に設定されているランタイムか、または実行環境で使利用可能な JavaScript ランタイムを選択しているようです。

def self.autodetect
  from_environment || best_available ||
    raise(RuntimeUnavailable, "Could not find a JavaScript runtime. " +
      "See https://github.com/sstephenson/execjs for a list of available runtimes.")
    # ↑ここで例外!
end

def self.best_available
  runtimes.find(&:available?)
end

def self.from_environment
  if name = ENV["EXECJS_RUNTIME"]
    if runtime = const_get(name)
      if runtime.available?
        runtime if runtime.available?
      else
        raise RuntimeUnavailable, "#{runtime.name} runtime is not available on this system"
      end
    elsif !name.empty?
      raise RuntimeUnavailable, "#{name} runtime is not defined"
    end
  end
end
…
def self.runtimes
  @runtimes ||= [
    RubyRacer,
    RubyRhino,
    Johnson,
    Mustang,
    Node,
    JavaScriptCore,
    SpiderMonkey,
…

RubyRacer がインストールされているはずなのに best_available が false を返している部分が想定と違う動きです。RubyRacerRuntime クラスの available? を追ってみます。

def available?
  require "v8"
  true
rescue LoadError
  false
end

どうも V8 エンジンのロードに失敗しているようです。コマンドラインから試してみると確かにネイティブライブラリのロードに失敗していました (「インストールされていない」ならともかく「インストールされているのにロードに失敗した」ならエラーログくらい出してもらいたいところです)。

torao@cumin$ ruby -e "require 'v8'"
/home/torao/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require': /home/torao/.rvm/gems/ruby-1.9.2-p290/gems/therubyracer-0.9.8/ext/v8/v8.so: cannot restore segment prot after reloc: Permission denied - /home/torao/.rvm/gems/ruby-1.9.2-p290/gems/therubyracer-0.9.8/ext/v8/v8.so (LoadError)
        from /home/torao/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
        from /home/torao/.rvm/gems/ruby-1.9.2-p290/gems/therubyracer-0.9.8/lib/v8.rb:6:in `'
…

で、cannot restore segment prot after reloc: Permission denied の原因は何かと調べてみたら、変な場所からライブラリをロードできないよう SELinux がブロックしていることが原因でした。開発用サーバのため rvm 流儀で $HOME/.rvm 以下に gem リポジトリが置かれたのがアダとなったようです。

とりあえず今回は開発用の動作環境ですので root で /etc/sysconfig/selinux を編集し SELINUX=disabled にして再起動しましたところこの問題は解消しました。本番環境などで SELinux を無効化したくない場合はこちらなどを参考に Ruby が参照している v8.so をロードする許可を与えてください。

三連休最後の一日がこれで潰れましたよ。とほほ…

Profile
Takami Torao
Takami Torao
C/C++ 使いだった 1996年、運命の Java と出会い現在に至る。のらアーキテクト。
Yah, this is image so I don't wanna eat spam, sorry!
Search

Google
MOYO Laboratory
Web

カテゴリー
最近の記事
最近のコメント
最近のトラックバック
月別アーカイブ
ブロとも申請フォーム
RSSフィード
リンク