Tiny RMI

佐藤一郎

大学院講義の教材用に作成したJava言語用RMI。なお、以前作ったプログラムを組み合わせて、のべ7,8時間で作った2000行強の短いプログラムですが、ソースコードも公開しますし、比較的素直に作ってありますから分散オブジェクトやモバイルエージェントのお勉強用にはなるでしょうし、修論レベルであればこのRMIの拡張で何とかなるでしょう。拡張可能性というか、研究ネタも示しておきますので参考にしてください。

ソースプログラム&バイナリのダウンロード

なお、電子メールなどで問い合わせ頂いて結構ですが、研究などを目的にこのシステムの拡張などに関わる質問は歓迎しますが、Java言語のインストールの仕方とか、Classpathの設定方法などの初級レベルの質問はご勘弁下さい。Java言語の初学者が扱える代物ではないと思います。また、このRMIはJava言語の標準でついてくるjava.rmi.*は一切使っていませんが、RMIの知識がないとわからないかもしれません。

なお、動作にはJDK1.2以上が必要です。

特徴

遠隔コンピュータ上にオブジェクトを生成し、そのオブジェクトのメソッド呼び出しを可能にします。このとき呼び出される側のコンピュータにORBServerというランタイムシステムを起動しておけばよく、生成されるオブジェクトを定義するクラスなどは呼び出す側のコンピュータからオンデマンドで転送します。また、メソッド呼び出しの引数などはJava言語の直列化機能を使ってデータ化した後に転送するので、いわゆるcall-by-value(正しくはcall-by-copy)が可能になっている。また、引数となるオブジェクトの定義に必要なクラスもオンデマンドに転送します。つまり、オブジェクトの生成やメソッド呼び出しの際に呼び出される側のコンピュータのクラスは使わないため、事前にクラスを配置する必要はなく、ソフトウェア開発中などクラスを頻繁に変更しているときには便利なツールになります。なお、Java言語の標準RMI、つまりjava.rmi.*は一切利用していません。

動作

オブジェクトの生成は呼び出す側のコンピュータのプログラムが下記のような処理を実行することにより開始される。

ORBServer orb = new ORBServer(local_port);
Message msg = new Message("java.awt.Frame");
msg.setArg("Tiny RMI Test Program");
ObjectId oid = orb.newInstance(host, remote_port, msg);

ここで、local_portは呼び出す側のコンピュータが使う通信用TCP/IPポート番号、hostは呼び出される側のコンピュータ名、remote_portは呼び出される側のコンピュータが利用する通信用ポート番号である。そして下図のように呼び出す側のコンピュータ(Computer A)から、呼び出される側コンピュータ(Computer B)に生成要求メッセージが送られる。

次に下図のようにComputer BはComputer Aに対して、オブジェクト生成に必要なクラスの転送を要求する。なお、現在の実装では動作がよくわかるようにjava.lang.Objectを含めて必要なクラスを一切合切送るように設定してある。また、Java言語の標準RMIではRemoteインターフェースに実装したクラス以外は呼び出すことができないが、このシステムはそうした呼び出し可能なクラスは呼び出す側(つまりComputer A)にあるクラスならば何でも良い。

オブジェクトが生成されるとComputer BはComputer Aにそのオブジェクトの識別子を送る。上述のプログラム例では変数oidにその識別子が格納される。

次にメソッド呼び出しについて説明する。呼び出し側プログラムで下記のような処理が行われたとする。

Message msg = new Message("print");
msg.setArg("Hello World");
orb.invoke(host, remote_port, oid, msg);

ここでprintは呼び出すオブジェクトのメソッド名、2行目ではそのメソッドの引数としてHello Worldという文字列を与えており、3行目ではhostで特定できるコンピュータ上のoidに識別されるオブジェクトにメソッド呼び出しを行う。その過程は次の通り。

このときも引数オブジェクトに必要なクラスをComputer AからComputer Bに転送する。

インストールとサンプルプログラムの実行

Java言語で記述されていることから、Java言語のインストールがまず必要である。JDK1.2以上のJava言語を用意する。そして、Tiny RMIパッケージを解凍・インストールし、次のようなディレクトリ(フォルダ)構成をもつディレクトリをカレントディレクトリーにする。

-|-<doc>
 |-<sample>
 |-<tinyrmi>

まず、呼び出される側のコンピュータのTerminalから次のようなコマンドを実行する。

java tinyrmi.ORBServer 5000

ここで5000とはTiny RMIが通信に使うポート番号であり、もし他の通信プログラムと重なっているときは他の番号を使えばよい。次にこのORBServerが稼働している状態で呼び出す側のコンピュータで次のコマンドを実行する。

java sample.HelloWorldClient host 5000 5001

ここでhostは呼び出されるコンピュータの名前である。一台しかコンピュータが用意できない場合はlocalhostでよい。また、5000は呼び出される側の通信用ポートと同じ番号にすること。この二つのコマンドを実行すると呼び出す側の命令で呼び出される側にオブジェクトが生成され、さらにメソッド呼び出しによって画面にHelloと表示する。その様子を示すと、まず呼び出す側のコンピュータの実行画面は下記となる。

ここで3行目が生成命令の送信を示し、fetched classを含む行は呼び出される側からクラスの転送要求を受け取っていることを示している。そして最後から3行目はメソッド呼び出しを示している。一方、呼び出される側は次のようになる

最後から2行目のHelloが画面表示である。

そのほかのサンプルプログラムも解説しおく

遠隔四則演算

呼び出される側のコンピュータで次のコマンドを実行

java tinyrmi.ORBServer 5000

そして、呼び出し側コンピュータで同時に次のコマンドを実行

java sample.CalculatorClient host 5000 5001

ここではhostや5000、5001はHelloWorldClientと同じである。

オブジェクト移動実験

呼び出される側のコンピュータで次のコマンドを実行

java tinyrmi.ORBServer 5000

そして、呼び出し側コンピュータで同時に次のコマンドを実行

java sample.WindowSendor host 5000 5001

ここではhostや5000、5001はHelloWorldClientと同じである。TextAreaによるエディタに文字を書き込み、SENDボタンを押すとそのTextAreaがその中身を保持したまま引数として呼び出される側コンピュータに送られる。なお、このサンプルでは転送されるオブジェクトはjava.awt.Componentの継承クラスに制限しているが、動作自体はいわゆるモバイルエージェントと同じであり、汎用のモバイルエージェントにするのは難しくないと思います。

教育研究用RMI?

このRMIは総合研究大学院大学情報学専攻科後期博士課程の講義用教材として作成されました。ただ、現状の国内修士課程(前期博士課程)の水準を考えると、修論ならば余裕でクリアできると思いますし、何らかの拡張を加えれば国内論文誌の論文程度には持っていけると思います。代表的な拡張事例をあげますので興味のある方は論文にしてみてください。

本当は授業の課題として考えていたものですが、海外大学とは違うと非難を受けてしまい、結局取りやめたものです。もっとも米国の一流大学の博士課程ならばこの程度のRMIは1ヶ月程度の課題でスクラッチから作れという課題がでると思いますけど。どちらにしても、うまくまとめれば国内論文誌ぐらいの論文にはなるでしょう。検討を祈ります。

 




Ichiro Satoh (E-mail: ichiro@nii.ac.jp)

Ph.D, Associate Professor
National Institute of Informatics
2-1-2 Hitotsubashi, Chiyoda-ku, Tokyo 101-8430 Japan
Tel: +81-3-4212-2546
Fax: +81-3-3556-1916