Tiny RMI

佐藤一郎

大学院講義の教材用に作成したJava言語用RMI。なお、ソースプログラムも提供するので参考にしてください。実質2000行強なので分散オブジェクトやモバイルエージェントのお勉強用に最適だと思います。

特徴

遠隔コンピュータ上にオブジェクトを生成し、そのオブジェクトのメソッド呼び出しを可能にします。このとき呼び出される側のコンピュータに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の継承クラスに制限しているが、動作自体はいわゆるモバイルエージェントと同じであり、汎用のモバイルエージェントにするのは難しくないであろう。