RMI の実装

RMI の実装は、3 つの抽象化層により構成されます。

3 つの抽象化層は、以下のとおりです。
  1. スタブおよびスケルトン層。クライアントによりインターフェース参照変数に対して行われたメソッド呼び出しを代行受信して、その呼び出しをリモート RMI サービスに転送します。
  2. リモート参照層。クライアントからリモート・サービス・オブジェクトに対して作成された参照を、どのように解釈および管理するのかを把握します。
  3. 最下層であるトランスポート層。ネットワーク内のマシン間の TCP/IP 接続に基づきます。 基本的な接続戦略およびファイアウォールの通過戦略を提供します。
この図は、RMI システムを介したクライアント・プログラムとサーバー・プログラムの関係を示しています。 RMI システムは、スタブとスケルトン、およびトランスポート層によってリンクされたクライアント・サイドとサーバー・サイドの両方のリモート参照層で構成されます。

TCP/IP 層の上部で、RMI は Java™ Remote Method Protocol (JRMP) と呼ばれるワイヤー・レベル・プロトコルを使用します。これは以下のように機能します。

  1. リモート動作を必要とするオブジェクトでは、RemoteObject クラスを拡張する必要があります。これは通常、UnicastRemoteObject サブクラスを介して行われます。
    1. UnicastRemoteObject サブクラスではリモート・オブジェクトをエクスポートして、着信 RMI 呼び出しの処理に使用できるようにします。
    2. リモート・オブジェクトのエクスポートにより、ポート番号にバインドされる新しいサーバー・ソケットが作成されます。
    3. そのソケットで接続を listen するスレッドも作成されます。 サーバーがレジストリーに登録されます。
    4. クライアントでは、レジストリーからサーバーに接続する際の詳細が取得されます。
    5. レジストリーからの情報 (ホスト名およびサーバーの listen ソケットのポートの詳細など) を使用して、クライアントはサーバーに接続します。
  2. クライアントでは、サーバーへのリモート・メソッド呼び出しの発行時に TCPConnection オブジェクトを作成します。このオブジェクトは、指定されたポートでサーバーへのソケットを開き、StreamRemoteCall クラスを使用して、この接続経由で RMI ヘッダー情報およびマーシャルされた引数を送信します。
  3. サーバー・サイド:
    1. クライアントがサーバー・ソケットに接続すると、着信呼び出しを処理する新規スレッドが割り当てられます。 元のスレッドは引き続き元のソケットを listen することができるため、他のクライアントから別の呼び出しを行うことができます。
    2. サーバーではヘッダー情報を読み取り、それ自身の RemoteCall オブジェクトを作成して、ソケットの RMI 引数のアンマーシャルを行います。
    3. Transport クラスの serviceCall() メソッドでは、着信呼び出しをディスパッチして提供します。
    4. dispatch() メソッドでは、オブジェクトで適切なメソッドを呼び出し、結果をワイヤー経由で戻します。
    5. サーバー・オブジェクトにより例外がスローされた場合、サーバーでは、戻り値の代わりに例外がキャッチされ、ワイヤー経由でマーシャルされます。
  4. クライアント・サイドに戻る:
    1. RMI の戻り値がアンマーシャルされ、スタブからクライアント・コード自身に戻されます。
    2. サーバーから例外がスローされた場合は、例外がアンマーシャルされてスタブからスローされます。