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

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