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