RedBridge について。その3 と netbeans の Rails サポート廃止の件

本題に入る前に、数日前にとても残念なニュースが飛び込んできた件について。

netbeans 7.0では、Rails のサポートが打ちきられてしまうことになってしまいました。


これは困ります。
Rails はテスト的に何度か使った事があるだけですが、netbeans を使わないと、warbler で war ファイルとかどうやって作ったらいいのかさえ、知らないし。IDE に頼りきりというもの考えものです。

Ruby 自体のサポートが切られたわけではありませんが、私が思いますに、これはたぶんオラクルの指示によるものと思いますし、その理由はおそらく salesforceruby 指示を打ち出した件と関係があるものと思います(勝手な憶測でしかありませんが)


要するに、オラクルにとって RubyJava を脅かすように思えてきたということではないかな、と。そうだとすれば、これに止まらず、将来的に netbeansRuby のサポートを打ち切ったとしても不思議ではありません。

現状、netbeansRuby を使うのにベストな存在だっただけに、とても残念です。
みんなどうするつもりなんでしょう? 私は Redcar を試してみようかな、と思っています。


IDE に慣れてしますと、リファクタリングとかソースの整形とか、コマンド1発で出来てくれないと、やってられない気がします。エディタでちまちまとか、信じられません。たぶん、Java の世界に馴染みのある人はみんなそういう感覚だと思います。前途多難ですね…


さて、Java から jruby を利用する仕組みである RedBridge (別名 JRuby Embed) の機能をさぐるの3回目です。


実は、RedBridge には動作モードを設定するオプションがいくつもあります。

これまでのサンプルでは、特段になんのオプションも定めなかったため、初期設定状態で動いていたことになります。しかし、この初期設定状態なるものが、なかなかに分かりにくい。


少なくとも、ローカル変数の共有状態に関しては(一時的、永続的、グローバル、およびBSFの)4種類があり、初期設定状態では 一時的 ( Transient Local Variable Behavior )というものです。

つまり、これまでのサンプルコードは、この 一時的 ( Transient Local Variable Behavior ) というものだったわけです。


このモードの特徴は、ローカル変数の有効範囲は、Rubyの文法に忠実 というものです。これだけならどうってことないわけですが、裏から見れば、Rubyの文法に忠実 でないモードもあるということになります。


モードにはこのほか、各種スレッドの動作指定モードや、コンパイル・モードなるものも別にあり、 jit かどうでないかなどを指定出来たりするようです。なにも指定してなければ、 jit にならないんでしょうか??? 調べなければ。



さて、以下に、RedBridge wiki ( http://kenai.com/projects/jruby-embed/pages/Home )  より、関係部分のみ抜粋試訳を掲げます。 (原文は青字)


Local Variable Behavior Options
ローカル変数の動作のオプション


Scope: Per Container
Property Name: org.jruby.embed.localvariable.behavior
Value: transient (default for core), persistent, global (default for JSR223), or bsf (for BSF)


JRuby Embed enables to share Ruby's local, instance, global variables, and constants.
JRuby Embed は、Rubyのローカル、インスタンスグローバル変数、および定数を共有することができます。


To share these variables between Ruby and Java, JRuby Embed offers four types of local variable behaviors, transient, persistent, global, and bsf.
RubyJavaの間でこれらの変数を共有するには、JRuby Embed は、ローカル変数の動作に関して、一時的、永続的、グローバル、およびBSFの4種類を提供しています。


Four types are defined in org.jruby.embed.LocalVariableBehavior and also can be set by a system property.
4つのタイプがorg.jruby.embed.LocalVariableBehaviorで定義されています。また、システムのプロパティで設定することができます。


Transient Local Variable Behavior
一時的なローカル変数の動作


Default for Embed Core.
Embed Core の初期設定 (★ つまり、今回の例はこの Transient Local Variable Behavior の事例にあたります)


Local variables' scope is faithful to Ruby semantics.
ローカル変数の有効範囲は、Rubyの文法に忠実です。 (★ つまり、今後示される事例では、そうでない場合がある)


This means local variable does not survive over the multiple evaluations.
これは、文脈上の区切りを越えては生存できないローカル変数を意味します。


After the each evaluation, local variable will vanish away.
各評価した後、ローカル変数は消え去るでしょう。


However, instance and global variables, and constants survive unless those are removed explicitly.
ただし、明示的に削除されない限り、インスタンス変数とグローバル変数、および定数は生き残ります。


If you use global variables, the variables can be referred literally globally in Ruby runtime and exist as long as the runtime is alive.
グローバル変数を使用する場合、その変数は、文字通りグローバル参照することができます
Rubyのランタイムで、ランタイムが生きている限り、存在しています。


Be careful to the scope of global variables so that you don’t mix in vulnerabilities in a web application.
Webアプリケーションの脆弱性を混合しないようにグローバル変数のスコープに注意してください。


Core
Embed Core での構文
(★ と同時に、よく見るとデフォルトの動作モードが示されている。その設定は LocalContextScope.SINGLETHREAD, LocalVariableBehavior.TRANSIENT。 jit の指定は特にないが、有効になってない?


ScriptingContainer instance = new ScriptingContainer();

or
ScriptingContainer instance = new ScriptingContainer(LocalVariableBehavior.TRANSIENT);

or

ScriptingContainer instance = new ScriptingContainer(LocalContextScope.SINGLETHREAD, LocalVariableBehavior.TRANSIENT);


この項、まだまだ続きます。では。

RedBridge について。その2

さて、Java から jruby を利用する仕組みである RedBridge (別名 JRuby Embed) の機能をさぐるの2回目です。

プロジェクト http://kenai.com/projects/jruby-embed から拾ってきた次なるサンプルコードはこれです。


● sample code 02


package vanilla;

import org.jruby.embed.ScriptingContainer;

public class SimpleEvalSample {

private SimpleEvalSample() {
System.out.println("[" + getClass().getName() + "]");
ScriptingContainer container = new ScriptingContainer();
container.put("message", "local variable");
container.put("@message", "instance variable");
container.put("$message", "global variable");
container.put("MESSAGE", "constant");
String script =
"puts message\n" +
"puts @message\n" +
"puts $message\n" +
"puts MESSAGE";
container.runScriptlet(script);
}

public static void main(String[] args) {
new SimpleEvalSample();
}
}

実行結果


[vanilla.SimpleEvalSample]
local variable
instance variable
global variable
constant


以上ですが、
これは単にコピペして貼り付けただけですので、実際に netbeans 上で問題なくこの通り動くかどうか確認して、その意味するところを考えてみましょう。


package 名は前回と同じく vanilla ですから、前回の Java プロジェクトを流用しちゃいましょう。package名が vanilla であるのを確認し、class名を選択し右クリックでリファクタリング


画像02_01 


画像02_02


class名を SimpleEvalSample にしたところで上記サンプルコードをコピーペースト。


画像02_03


実行ボタンをクリック。


画像02_04


エラーが出たときは、まず jruby-complete-1.5.6.jar (JRuby そのものであるところの Java ライブラリ)がきちんと取り込まれているかチェックしてください。


この例のように、前回のプロジェクトを流用した場合はもともと取り込まれていますけれど、新規にプロジェクトを作成した場合は、改めてプロジェクト名を右クリックしプロパティーを選択。ライブラリのところからjar フォルダを追加 ボタンをクリックして、jruby-complete-1.5.6.jar を選択して取り込みます。(前回の記事を参考にしてください)


また、Java のプロジェクトは最終的に jar にするのが普通ですが、ここではもう説明しませんけど、jar の作り方も前回の記事を見てください。jar の作り方は、必ず知ってないとダメだと思いますよ。(実行メニューの プロジェクトを削除して構築 を実行。jar の入った distフォルダが作成される)


さて、ところでこのサンプル・コードの意味するところはなんでしょう????

じっくり今回のサンプル・コードを見てみますに、


ScriptingContainer container = new ScriptingContainer();

で、jrubyインスタンスを作成し、


container.put("message", "local variable");
container.put("@message", "instance variable");
container.put("$message", "global variable");
container.put("MESSAGE", "constant");

で、ローカル変数、インスタンス変数、グルーバル変数、定数をそれぞれその jruby インスタンス に作成し、それを次の


String script =
"puts message\n" +
"puts @message\n" +
"puts $message\n" +
"puts MESSAGE";
container.runScriptlet(script);

で、読み出しているということになるでしょう。


jruby をその中に立ち入らず、外部から java で操作しているという感じと言っていいのでしょうか? また、複数のjruby インスタンスを作りだし、並行動作させることも出来そうですが、ここではそれには立ち入らないことにします。


この項、まだまだ続きますよ。では。

RedBridge について。その1

RedBridge とは JRuby Embed の別名で、Java から jruby を利用する仕組みの事です。yoko harada さんらが中心になってやっているようです。

(ちなみに、私は縁もゆかりもありません。適当な日本語の解説が私が捜した範囲では見つけられなかったので、自分が分かる範囲でなにか書こうと思っただけです)

プロジェクトのトップページは http://kenai.com/projects/jruby-embed で、その wiki から詳細を知る事が出来るようです。

まず、その wiki にあるもっとも簡単なサンプルを拾ってきて、実際に試してみましょう。


● sample code 01


package vanilla;

import org.jruby.embed.ScriptingContainer;

public class HelloWorld {

private HelloWorld() {
ScriptingContainer container = new ScriptingContainer();
container.runScriptlet("puts \"Hello World!\"");
}

public static void main(String[] args) {
new HelloWorld();
}
}

というもので、内容は Java から JRuby を使い、Hello World! を表示しようというものです。

そのままやってみればいいだけですが、ここでは IDE として netbeans を使い、ポータブルな jar ファイルまで作成してみます。

netbeans 6.9.1 ( http://ja.netbeans.org/ )から java のプロジェクト(ruby のプロジェクトじゃなくて)を作成します。(なお、筆者の環境は Linux ubuntu 10.04 です。文字コードutf-8 がデフォルトです)


○画像01 ruby プロジェクトではなくて、 Java プロジェクトですよ。


せっかくだから、サンプルのコードを IDE でやりやすいように適当に変えたりしないで、そのまま忠実に実行しようと思います。

ですから、package 名も vanilla とするため、netbeans でプロジェクト生成時にプロジェクト名をvanilla にしてしまいます。


画像02 プロジェクト名を vanilla に。


(プロジェクト名を package 名 にしなくてもいいのですけど、package 名を別にしようとすると、なかなか面倒なのです。もし後から package 名だけ vanilla に変えるなら、メインプログラムの package名 を選択して右クリックし 現れたメニューの中の リファクタリングで名称変更するだけでなく、プロジェクト名を右クリックし現れたメニューの中の プロパティーを選択。現れたダイアログの 実行を選択。主クラスで vanilla.HelloWorld と指定しなおす必要があるでしょう)


ダイアログで 完了ボタン をクリックすると、めでたくプロジェクトが生成されます。

(実はこの時、ダイアログの 主クラスを作成 のところで名前を Main から変更しておくと、主クラスの名前を好きな名に出来るのですが、応用を考えて、後からリファクタリングします)


このとき、一緒にテンプレート・コードも生成されているのですが、その class は Main という名前です。その class 名を サンプル・コードに合わせて HelloWorld に変更しようと思います。(単に変更するのではなく、ファイル名も変更しないといけません)

そこで class 名の Main を選択して右クリックしてリファクタリング の 名前を変更 を選択します。(最初に ダイアログの 主クラスを作成 のところで名前を変更した場合は、リファクタリングは必要ありません。)


画像03


画像04


出てきたダイアログの 新しい名前に HelloWorld と入力し、プレビューボタンをクリック。内容を確認しつつ、リファクタリングを実行します。


さて、これで下準備は出来ました。
( package名や class名が sample code 01 と合致したということ」)
sample code 01 を プロジェクトの HelloWorld.java にコピー・ペーストで貼り付けてしまいましょう。


画像05


さて、これで用意万端、実行ボタンを押しましょう、と言いたいところですが、
まだそうはいきません。画像05 よく見てください。HelloWorld.java の行頭の何ヶ所かに赤丸印が付いています。なにかが不足しているのです。

どういう事かというと、サンプル・コードで JavaJRuby を呼び出しているのに、その JRuby の実体がどこにも指定されていないのが原因です。

そのためにはまず jruby-complete.jar が必要になります。
これは JRuby の機能が詰め込まれた JRuby そのものである Java のライブラリです。http://jruby.org/download から jruby-complete-1.5.6.jar を入手して下さい。


画像06 http://jruby.org/


画像07 http://jruby.org/download


netbeans のプロジェクト・ウィンドウでプロジェクト名を右クリックして、プロパティーを選択して、プロパティー・ダイアログを出します。


この プロパティー・ダイアログ の ライブラリを選択。jar フォルダを追加 ボタンをクリックして、jruby-complete-1.5.6.jar を選択します。


画像08


画像09


画像10


これで、HelloWorld.java の行頭に出ていたエラーの赤丸印も消えるので、いよいよ実行ボタンを押します。(実行ボタンは次の画像のカーソルのところのボタン)
めでたく HelloWorld! と表示されたはずです。いかがでしょうか?


画像11


さて、Java ではファイルの持ち運びのためには、Jar ファイルを作成します。
この vanilla プロジェクトの Jar ファイルはどこにあるのでしょうか?

ホームディレクトリにある NetBeansProjects フォルダの中を捜してみましょう。


画像12 NetBeansProjects フォルダの中身( 環境は Linux Ubuntu 10.04 )



ちょっと見たところ、ないようです。(実行の際のやり方によっては、すでに Jar ファイルが出来ている場合もあります)

そこで、実行メニューの プロジェクトを削除して構築 を実行します。


画像13 実行メニューの プロジェクトを削除して構築 を実行


もう一度、ホームディレクトリにある NetBeansProjects の中を見てみます。
すると今度は、dist フォルダというものが出来ています。その中を見てみると、ありました。 vanilla.jar が。


画像14 NetBeansProjects の中身


画像15 dist フォルダの中身。vanilla.jar がある。


さらに、その中の lib フォルダを開いてみます。するとその中には、jruby-complete-1.5.6.jar がコピーされています。


画像16


この Jar ファイルの持ち運びは、dist フォルダごと運びます。
フォルダの名は適当に変えていいですが、中身はいじらないように。

Jar ファイルの実行の仕方はこうです。

とりあえず動作確認のため、dist フォルダ をホームディレクトリにコピーして、
その名前を dist_test フォルダと変更しておきましょう。

ファイルの実行の仕方は、フォルダ内の README.TXT に書いてありますが、ターミナル( windows でのコマンド・プロンプト)で

java -jar "vanilla.jar"

です。が、その前にカレントディレクトリを dist_test フォルダにておかないと
いけません。 Linux ( ubuntu 10.04 ) の場合は、次の画像のようにやります。
(すいません。私は ms-windows でのやり方はよく知りません)


画像17 カレントディレクトリを cdコマンド で移動し ls コマンドで内容を表示、
続いて jar を実行。 Hello World! と表示される。


jar ファイルのいいところは、これが GUIアプリケーションならば、ダブルクリック するだけで実行されること。いずれ GUIアプリに挑戦しましょう。

さて、RedBridge 、今回はここまで。次回以降も続きます。では。

はじめに

最近、よく jruby で遊んでます。
そんなわけで、気の向くままに jruby にまつわる何かを
書いていきたいな、と。
最初に取り上げたいと思うのは、java から jruby を使うという
RedBridge にしようと思ってます。
まあ、それより前にこのブログの操作方法を覚える方が先ですね(笑)
のんびりゆっくりいきたいと思ってます。
では。