RMI-IIOP

RMI-IIOP（RMI オーバー IIOP）とは、CORBAシステム上のJava RMIインタフェースを指す。 この標準は、CORBA の利点を保ちつつ、CORBA アプリケーションの開発を単純化するべく作成された。RMI-IIOP は、CORBA 構造体、共用体、シーケンス、配列、文字列などを置換するコンテナとして働く Object by Value の概念に基づいている（CORBAの項目を参照）。IDLは使われていない。代わりに自動的にデータ構造定義を推定し、リフレクション機構で必要なデータを集める。CORBA では転送すべきデータ構造ごとに補助的なクラスを生成する必要があるが、RMI-IIOP ではリモートオブジェクト向けに生成されたコードを使うだけでよい。生成すべきコード量が少ないため、メモリ使用量も減らせる。 CORBA と RMI-IIOP はどちらも通信規格の GIOP を使用している。RMI-IIOP のデータ構造について、必要ならばIDLを生成することも可能で、それを使って、RMI-IIOP と 純粋な CORBA アプリケーションの相互運用を行うことも可能である。 RMI-IIOP の最近のバージョンでは標準のサーバントクラスからサーバントを生成できる。これを使うと CORBA の ORB に手動で接続でき、Portable Object Adapter、Portable Interceptor、CORBA のネーミングサービスなどの各種 CORBA 機能に接続可能である。 Java RMI-IIOP を実装したパッケージの標準的な名称は javax.rmi.CORBA である。 public interface MyServer extends Remote { // クライアントは self を第一引数に渡す。サーバはクライアント側 // にあるリモートメソッドを呼び出せる。これは要求処理に時間がかかる場合に // 便利である。 void receiveRequest(MyClient client, String message) throws RemoteException; } public interface MyClient extends Remote { // このリモートメソッドはサーバから呼び出される void receiveReply(String message) throws RemoteException; } public class MyServerImpl implements MyServer { void receiveRequest(MyClient client, String message) throws RemoteException { System.out.println("The client says: "+message); client.receiveReply("Yes, "+message+", "+message+", "+message+"..."); } } public class MyClientImpl implements MyClient { MyServer server; public MyClientImpl(String Server_IOR, ORB orb) throws Exception { server = (MyServer) PortableRemoteObject.narrow( orb.string_to_object(Server_IOR), MyServer.class); } // これはリモートメソッド void receiveReply(String message) throws RemoteException { System.out.println("And the answer is: "+message); } // これはリモートメソッドではなく、ローカルメソッド public void talk(String conversation) { server.receiveRequest(this, conversation); } } RMI-IIOP 開発ツール（rmic）は上記2つのクラスを使い、リモート側で使われる2つのスタブとサービス側で使われる2つの Tie を生成する。つまり、スタブと Tie のペアがそれぞれクライアント側とサーバ側に置かれる。 new Thread() { public void run() { try { // CORBA ORB の生成 MyServerImpl.orb = ORB.init(args, properties); // ルート Portable Object Adapter を取得: POA rootPOA = POAHelper.narrow (MyServerImpl.orb.resolve_initial_references("RootPOA")); // MyServerImpl にはサーバがサポートしなければならない // メソッドの実装が含まれる。 MyServerImpl impl = new MyServerImpl(); PortableRemoteObject.exportObject(impl); // Tie の構築。Tie はサーバントでもある。 // _MyServerImpl_Tie クラスは MyServerImpl から自動的に生成される。 Tie tie = new _MyServerImpl_Tie(); // この Tie の呼び出しターゲットを設定 tie.setTarget(impl); // 対応する CORBA オブジェクトへの参照を取得: org.omg.CORBA.Object object = rootPOA.servant_to_reference((Servant) tie); // ルート POA の活性化 rootPOA.the_POAManager().activate(); // クライアントに渡す IOR URL を取得 String Server_IOR = MyServerImpl.orb.object_to_string(object); MyServerImpl.orb.run(); // 文字列変数 Server_IOR の内容をどうにかしてクライアントに // 転送しなければならない } catch (Exception exc) { exc.printStackTrace(); } } }.start(); MyClient the_client; new Thread() { public void run() { try { ORB orb = ORB.init(args, parameters); the_client = new MyClientImpl(Server_IOR, orb); POA rootPOA = POAHelper.narrow(desk.orb.resolve_initial_references("RootPOA")); rootPOA.the_POAManager().activate(); // Tie 構築 Tie tie = new _MyClientImpl_Tie(); // 実装クラス（呼び出しターゲット）の設定 tie.setTarget(the_client); // Tie を POA サーバントとして接続 org.omg.CORBA.Object object = rootPOA.servant_to_reference((Servant) tie); // IOR 文字列を使ってWeb上でこのオブジェクトを探すことが可能 String IOR = desk.orb.object_to_string(object); orb.run(); } catch (Exception exc) { exc.printStackTrace(); } } }.start(); ORB スレッドが開始した後で、以下のコードを実行する: the_client.talk("it is raining"); 最初にサーバ、次にクライアントがそれぞれ別のマシン上で開始される（同一マシンの別プロセスでもよい）。サーバは The client says: it is raining と表示する。クライアントは And the answer is: Yes, it is raining, it is raining, it is raining.. と表示する。 ここに示したコードはサン・マイクロシステムズの Java 1.5 と GNU Classpath 0.95 で動作する。 IIOP という略称はOMGの商標であり、利用には注意が必要である。このプロトコルは GIOP 上にあるため、GIOPを利用しているとした方がよい場合もある。これは間違いではないが、やや正確さを欠く（GIOP の実装は他にも様々存在する）。詳しくはGIOPを参照されたい。 The official RMI-IIOP standard from the OMG group (direct download, .pdf, about 890 Kb). The official CORBA standard from the OMG group (direct download, .pdf, about 10 Mb).