目次 | 前の項目 | 次の項目 | Java Remote Method Invocation |
UnicastRemoteObject
クラスjava.rmi.server.UnicastRemoteObject
クラスは、リモートオブジェクトの作成とエクスポートをサポートします。このクラスは、次の特性を持ったリモートサーバオブジェクトを実装します。
package java.rmi.server; public class UnicastRemoteObject extends RemoteServer { protected UnicastRemoteObject() throws java.rmi.RemoteException {...} protected UnicastRemoteObject(int port) throws java.rmi.RemoteException {...} protected UnicastRemoteObject(int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws java.rmi.RemoteException {...} public Object clone() throws java.lang.CloneNotSupportedException {...} public static RemoteStub exportObject(java.rmi.Remote obj) throws java.rmi.RemoteException {...} public static Remote exportObject(java.rmi.Remote obj, int port) throws java.rmi.RemoteException {...} public static Remote exportObject(Remote obj, int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws java.rmi.RemoteException {...} public static boolean unexportObject(java.rmi.Remote obj, boolean force) throws java.rmi.NoSuchObjectException {...} }
1 つまたは複数のリモートインタフェースを実装するリモートオブジェクト実装を 1 つ作成し、エクスポートする必要があります。リモートオブジェクトをエクスポートすることにより、そのオブジェクトは、クライアントからの呼び出しを受け入れることができるようになります。UnicastRemoteObject
としてエクスポートされるリモートオブジェクト実装の場合は、エクスポートには TCP ポートでの待機が含まれます。ただし、同じポート上で複数のリモートオブジェクトが着信する呼び出しを受けられるので、必ずしも新しいポートで待機する必要はありません。リモートオブジェクト実装では、UnicastRemoteObject
クラスを拡張してオブジェクトをエクスポートするコンストラクタを利用するか、あるいはほかのいくつかのクラスを拡張して (またはまったく拡張せずに)UnicastRemoteObject
のexportObject
メソッドを使ってオブジェクトをエクスポートすることができます。引数のないコンストラクタは、リモートオブジェクトを作成し、実行時に選択された匿名 (または任意) のポートにエクスポートします。2 つ目の形式のコンストラクタは、port という引数を 1 つだけ取ります。 この引数は、リモートオブジェクトが着呼を受け入れるポート番号を指定します。3 つ目のコンストラクタは、
RMIClientSocketFactory
から作成されたServerSocket
を使って、指定されたport
の着呼を受け入れるリモートオブジェクトを作成してエクスポートします。 クライアントは、RMIClientSocketFactory から提供されたSocket
を使ってリモートオブジェクトに接続します。
RemoteObject
からの拡張ではない実装のエクスポート
exportObject
メソッド (すべての形式) は、UnicastRemoteObject
クラスを拡張することでは実装されない単純なピアツーピアリモートオブジェクトをエクスポートするために使用します。exportObject
メソッドの 1 つ目の形式は、obj というパラメータを 1 つだけ取ります。 これは、着信する RMI 呼び出しを受け入れるリモートオブジェクトです。 このexportObject
メソッドは、実行時に選択された匿名 (または任意) のポートにオブジェクトをエクスポートします。2 つ目のexportObject
メソッドは、リモートオブジェクト obj、およびリモートオブジェクトが着呼を受け入れるポート番号 port の 2 つのパラメータを取ります。3 つ目のexportObject
メソッドは、指定されたRMIClientSocketFactory
csf
、および RMIServerSocketFactory ssf を使って指定された port にオブジェクト obj をエクスポートします。
exportObject
メソッドは、リモートオブジェクトobj
のスタブであり、リモートオブジェクトの代わりに RMI 呼び出しで渡されたRemoteStub
を返します。
UnicastRemoteObject
を渡す
上述したように、RMI 呼び出しの中で、エクスポートされたUnicastRemoteObject
型のオブジェクトがパラメータまたは戻り値として渡されると、このオブジェクトは、リモートオブジェクトのスタブに代わります。エクスポートされたリモートオブジェクトの実装は、それが作成された仮想マシン内にとどまり、仮想マシンから (値渡しによってさえ) 移動しません。すなわち、エクスポートされたオブジェクトは RMI 呼び出しでは参照渡しであり、エクスポートされたリモートオブジェクトの実装は、値では渡すことができないということになります。
UnicastRemoteObject
を直列化する
UnicastRemoteObject
に含まれている情報は一時的であり、その型のオブジェクトがユーザ定義のObjectOutputStream
に書き込まれた場合には保存されません (たとえば、オブジェクトが直列化を使用してファイルに書き込まれる場合)。ただし、UnicastRemoteObject
のユーザ定義サブクラスのインスタンスであるオブジェクトは、そのオブジェクトが直列化された場合でも保存可能な、非常駐データでないデータを持つことができます。
UnicastRemoteObject
が、UnicastRemoteObject
のreadObject
メソッドを使ってObjectInputStream
から読み込まれる場合、そのリモートオブジェクトは、RMI 呼び出しを受け取れるように RMI ランタイムに自動的にエクスポートされます。オブジェクトのエクスポートが何らかの原因で失敗した場合には、オブジェクトの直列化復元は、例外とともに途中で終了します。
UnicastRemoteObject
をアンエクスポートする
unexportObject
メソッドを使うと、着呼がリモートオブジェクト obj を利用できなくなります。force パラメータが true の場合は、たとえそのリモートオブジェクトに対する保留中または進行中の呼び出しがある場合でも、オブジェクトは強制的にアンエクスポートされます。force パラメータが false の場合は、オブジェクトに対する保留中または進行中の呼び出しがない場合だけ、オブジェクトがアンエクスポートされます。オブジェクトが正常にアンエクスポートされた場合は、RMI のランタイムによってそのオブジェクトが内部テーブルから削除されます。このような強制的な方法でオブジェクトをアンエクスポートすると、クライアントがリモートオブジェクトへの無効なリモート参照を保持したままになることがあります。オブジェクトが事前に RMI のランタイムにエクスポートされていない場合は、このメソッドは、java.rmi.NoSuchObjectException
をスローします。
clone
メソッド
オブジェクトの複製は、オブジェクトがjava.lang.Cloneable
インタフェースをサポートしている場合に、Java 言語のデフォルトの機構を使うことによってのみ可能になります。java.rmi.server.UnicastRemoteObject
クラスは、このインタフェースを実装していませんが、サブクラスがCloneable
を実装する必要がある場合に、そのリモートオブジェクトが正しく複製されるように、clone
メソッドを実装しています。サブクラスは、clone
メソッドを使って、始めの部分は同じ内容のリモートオブジェクトの複製を作成できます。 ただし、この複製は、エクスポートされてリモート呼び出しを受け付けるため、元のオブジェクトとは別のオブジェクトです。