| 目次 | 前の項目 | 次の項目 | 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メソッドは、指定されたRMIClientSocketFactorycsf、および 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メソッドを使って、始めの部分は同じ内容のリモートオブジェクトの複製を作成できます。 ただし、この複製は、エクスポートされてリモート呼び出しを受け付けるため、元のオブジェクトとは別のオブジェクトです。