JRuby

JRuby は、RubyインタプリタのJavaによる実装である。フリーソフトウェアであり、CPL/GPL/LGPL の3つのライセンスを採用している。JRuby はJavaと密に連携しており、インタプリタを任意のJavaアプリケーションに埋め込むことができ、JavaとRubyのコード間で双方向のアクセスを可能にしている。 JRuby の主な開発者は Charles Nutter[1]、Thomas Enebo[2]、Ola Bini[3]、Nick Sieger[4] である。2006年9月、サン・マイクロシステムズは Enebo と Nutter を雇用し、仕事として JRuby の開発をさせている。2007年6月、ThoughtWorks は Ola Bini を雇用し、Ruby と JRuby に関する仕事をさせている。 2009年7月、JRubyの開発者らはサンを離れ、Engine YardでJRubyの開発を継続している。 JRuby は2001年、Jan Arne Petersen が開発した。その当時（およびそれから数年間）、そのコードは Ruby 1.6 のC言語コードの直接的な移植に過ぎなかった。Ruby 1.8.6 のリリースをきっかけとして、JRuby を 1.8.6 対応させる作業が開始された。2001年からプロジェクトには何人かのコントリビュータが参加し、最終的に現在の4人を中核とするチームになった。 NetBeans Ruby Pack は NetBeans 6.0 から利用可能になっており、Ruby および JRuby の統合開発環境として利用できると共に、2つのRuby実装での Ruby on Rails の開発環境としても利用できる。 JRuby 1.1 は実行時コンパイラと事前コンパイラを追加し、Ruby 1.8.6 リファレンス実装よりも多くの場合高速に動作する。 JRuby 1.1.1 は Fedora 9 にパッケージとして含まれるようになった。 バージョン 1.1.1 以降、JRubyチームはポイントリリースを頻繁に行い、ユーザーに指摘された問題に素早く対処するようにしている。 2015年7月22日「JRuby 9.0.0.0」をリリースした。約3年ぶりのメジャーリリースとなり、Ruby 2.2系と互換性がある。 JRuby はバージョン 0.9（2006年5月）以降 Ruby on Rails をサポートしており、同時に RubyGems と WEBrick の実行も可能である。サンが2人の開発者を雇って以来、Rails 対応と性能は大幅に強化されてきた。JRuby バージョン 1.0 は Rails のテストケースのほとんどにパスした。その後、JRuby を Rails アプリケーション開発環境に使う開発者がでてきた。 2008年2月27日、サン・マイクロシステムズと東京大学は、RubyまたはJRubyアプリケーションを複数同時に1つのインタプリタ上で実行できる仮想機械の実装を行う共同研究プロジェクトを発表した。 JSR 292 (Supporting Dynamically Typed Languages on the JavaTM Platform) は以下を提案している。 新たに JVM レベルで invokedynamic 命令を追加し、動的型検査に基づくメソッド呼び出しを可能にする。 実行時に動的にクラスやメソッドを変化させられるようにする。 サンのオープンソースプロジェクト Da Vinci Machine で、このJSRのプロトタイプ実装を行っている。最初のプロトタイプは OpenJDK のパッチとして開発され、2008年8月末に完成が発表された。 JRubyチームは、非常に簡単な方法だが、コードベースに動的呼び出しを組み込んだ。動的呼び出しは次の 1.1.5 でリリースされ、動的呼び出しのないJVM上ではそれが機能しないようにしておくことになる。 2006年初めごろから、JRubyチームはそれまでのC言語コードの単なる移植からJavaのバイトコードを生かした高性能の実装にする努力を開始した。そして、JRuby を使って Ruby on Rails に全く手を加えずにそのまま実行できるようにすることを目標とした。その過程でJRubyのテストスイートも拡張され、JRubyの「正しさ」を保証する役目を果たした。結果として2006年末から2007年初めにはJRubyの中核部分の再設計とリファクタリングにとりかかることが可能になった。 JRuby は複数モードの Ruby 用仮想機械として設計されている。コードは直接インタプリタで解釈実行されるだけでなく、JITコンパイラでJavaバイトコードに実行時にコンパイルされたり、AOTコンパイラで実行前にJavaバイトコードにコンパイルされたりする。2007年10月まではインタプリタモードしかなかったが、バージョン1.1からAOT/JITコンパイラがサポートされるようになった。これらのモードは混在可能であり、また生成したバイトコードからJavaクラスファイルを生成することもできる。 JRuby は基本的には Ruby インタプリタだが、Javaで実装されている点が異なる。JRuby と Ruby は基本的に同じだが、JRuby では Java との緊密な連携が可能である。 JRuby の強力な機能の一つとして、Javaプラットフォームのクラスを呼び出すことができる。これをするには、まず "include Java"（以前のバージョンでは "require 'java'"）として JRuby の Java サポートをロードする。以下の例は、Javaの JFrame に JLabel を付与したものを生成する。 include Java frame = javax.swing.JFrame.new() frame.getContentPane().add(javax.swing.JLabel.new('Hello, World!')) frame.setDefaultCloseOperation(javax.swing.JFrame::EXIT_ON_CLOSE) frame.pack() frame.set_visible(true) また、JavaコードをよりRuby的なアンダースコアを使った命名規則で呼び出し、JavaBeanのプロパティを属性として参照できる。 frame.content_pane.add label frame.visible = true JRuby は容易に Java から呼び出すことができ、それには JSR 223 Scripting for Java 6 か Bean Scripting Framework を使う。詳しくは JRuby Wiki を参照されたい。 JRuby は上述したように、インタプリタモード、AOTモード、JITモードをサポートしている（後2者はバージョン1.1から）。 このモードでは、JRuby は標準の Ruby リファレンス実装よりも遅い。 例えば、Rails 処理をインタプリタモードで行うと Ruby 1.8 のリファレンス実装に比べて 50% から 70% 遅い。 Ruby 1.9 (YARV）ベンチマークを Java 6 で使ってみると、JRuby は Ruby の4倍の遅さである（立ち上げ時間を含む）。 JITモードは JRuby 1.1 から利用可能である。ベンチマークの結果から見れば、Ruby 1.8 リファレンス実装よりも高速である 。ただし Ruby 1.9 よりは低速である。しかし、JRubyチームは 1.1 の性能が Ruby 1.9 をも一部ベンチマークで凌駕しつつあると指摘している。 また、実際のアプリケーションであるMongrelというWebサーバでは、Ruby よりも JRuby の方が性能がよい（JVM立ち上げ完了後）。 サーバVMのままさらにインタプリタからコンパイルモードに変えると、ほとんどRuby 1.9.1と変わらない実行速度を実現しており、さらに各種最適化を実施することで実行速度は向上し、How JRuby Makes Ruby Fastで紹介している限りでは最終的にRuby 1.8.6よりも50倍、Ruby 1.9.1よりも10倍高速な実行速度が計測されている。