目次 | 前 の項目 | 次の項目 | Java Remote Method Invocation |
リモートオブジェクトへの引数、リモートオブジェクトからの戻り値は、直列化可能なオブジェクトであればどれでも可能です。これにはプリミティブ型、リ
モートオブジェクト、java.io.Serializable
インタフェースを実装した非リモートオブジェクトが含まれます。クラスを直列化可能にする方法の詳細については、「Java
オブジェクト直列化仕様」を参照してください。ローカルでは入手できないパラメータまたは戻り値のクラスは、RMI
システムによって動的にダウンロードされます。RMI
がパラメータ、戻り値、例外を読み取る際にパラメータおよび戻り値のクラスをダウンロードする方法の詳細については、「クラスの動的なロード」を参照してください。
リモートメソッド呼び出しのパラメータとして渡されたり、リモートメソッド呼び出しの結果として戻される非リモートオブジェクトは、コピーにより渡されま す。 つまり、非リモートオブジェクトは、Java プラットフォームのオブジェクト直列化機構を使って直列化することができます。したがって、リモートメソッド呼び出しで非リモートオブジェクトが返されるとき、非リモートオブジェクトの内容は、リモートオブジェクトの呼び出しが呼び 出される前にコピーされます。
リモートメソッド呼び出しから非リモートオブジェクトが戻されるときは、呼び出し側の仮想マシンに新規オブジェクトが作成されます。
リモートメソッド呼び出しで、エクスポートされたリモートオブジェクトをパラメータまたは戻り値として渡す場合には、そのリモートオブジェクトのスタブが 代わりに渡されます。エクスポートされていないリモートオブジェクトは、スタブインスタンスに置き換えられません。パラメータとして渡されたリモートオブ ジェクトは、リモートインタフェースだけを実装することができます。
単一のリモートメソッド呼び出しで、あるオブジェクトへの 2 つの参照が、ある JVM から別の JVM へパラメータ (または戻り値) として渡され、それらの参照が送信側の JVM 上の同一オブジェクトを参照している場合、これらの参照は、受信側の JVM 上のオブジェクトの 1 つのコピーも参照します。さらに一般的に説明すると、単一のリモートメソッド呼び出し内では、RMI システムは、呼び出し内でパラメータとして渡されたり、戻り値として返されるオブジェクト間の参照の整合性を維持します。
リモートメソッド呼び出しで、ある JVM から別の JVM にオブジェクトを送信する際に、RMI システムは呼び出しストリーム内のクラス記述子にクラスの情報 (URL) を注釈として付け、受信側でクラスをロードできるようにします。リモートメソッド呼び出し中には、必要に応じて随時、クラスをダウンロードする必要があり ます。
リモート呼び出し先に渡すパラメータを直列化するために、RMI 呼び出し内のパラメータは、java.io.ObjectOutputStream
クラスのサブクラスであるストリームに書き込まれます。ObjectOutputStream
サブクラスは、replaceObject
メソッドをオーバーライドして、エクスポートされた各リモートオブジェクトを対応するスタブインスタンスで置き換えます。オブジェクトであるパラメータ は、ObjectOutputStream
のwriteObject
メソッドを使ってストリームに書き込まれます。ObjectOutputStream
は、writeObject
メソッドによってストリームに書き込まれた各オブジェクト (書き込まれたオブジェクトによって参照されているオブジェクトも含む) の、replaceObject
メソッドを呼び出します。RMI のサブクラスObjectOutputStream
のreplaceObject
メソッドの戻り値は、次のとおりです。
replaceObject
に渡されたオブジェクトがjava.rmi.Remote
のインスタンスであり、そのオブジェクトが RMI ランタイムにエクスポートされた場合、リモートオブジェクトのスタブが返される。オブジェクトがjava.rmi.Remote
のインスタンスであり、そのオブジェクトが RMI ランタイムにエクスポートされない場合、replaceObject
はオブジェクト自体を返す。リモートオブジェクトのスタブは、java.rmi.server.RemoteObject.toStub
メソッドへの呼び出しによって取得されるreplaceObject
に渡されたオブジェクトがjava.rmi.Remote
のインスタンスでない場合は、単にそのオブジェクトが返される
RMI のサブクラスObjectOutputStream
もannotateClass
メソッドを実装し、クラスが呼び出し側でダウンロードできるように呼び出しストリームにクラスの場所についての注釈を付けます。annotateClass
の使用方法の詳細は、「クラスの動的なロード」を参照してください。どのパラメータも同一の
ObjectOutputStream
に書き込まれるため、呼び出し側で同じオブジェクトを参照している参照は、受信側でも同じオブジェクトのコピーを参照します。受信側では、パラメータは同 一のObjectInputStream
によって読み取られます。オブジェクトの書き込み用の
ObjectOutputStream
(および読み取り用のObjectInputStream
) のその他のデフォルトの動作は、パラメータの引き渡しで維持されます。たとえば、オブジェクトの書き込み時のwriteReplace
の呼び出し、およびオブジェクトの読み取り時のreadResolve
の呼び出しは、RMI のパラメータ整列化および非整列化ストリームで優先されます。戻り値 (または例外) も上記の RMI でのパラメータの引き渡しと同じ方法で
ObjectOutputStream
サブクラスに書き込まれ、パラメータの転送と同じ方法で置き換えられます。