fc2ブログ
ホーム   »  Ruby  »  "Could not find a JavaScript runtime" と Rails 3.1 起動に失敗する件

"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 をロードする許可を与えてください。

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

コメント
トラックバック
トラックバック URL
コメントの投稿
管理者にだけ表示を許可する
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フィード
リンク