| 目次 | 前へ | 次へ | Java Remote Method Invocation |
java.net.Socket および java.net.ServerSocket が必要です。RMI ランタイム実装は、これらのクラスのオブジェクトを直接初期化するのではなく、static メソッド RMISocketFactory.getSocketFactory によって返される、現在の RMISocketFactory オブジェクトの createSocket および createServerSocket メソッドを呼び出します。これにより、アプリケーションは、java.net.Socket および java.net.ServerSocket クラスの代替サブクラスなどの RMI 転送で使われるソケットの種類をカスタマイズするためのフックを保持できます。使用される RMISocketFactory のインスタンスは、信頼できるシステムコードによって一度に設定できます。JDK1.1 では、このカスタマイズは、ソケットの種類についての全般的な設定を行う場合に限られていました。これは、ファクトリのメソッドに渡されるパラメータが、createSocket の host と port、および createServerSocket の port だけであったためです。
Java SE プラットフォームでは、リモートオブジェクトとの通信にどのプロトコルを使うかについて、より柔軟にカスタマイズできるようにするため、新しいインタフェース RMIServerSocketFactory および RMIClientSocketFactory が導入されました。
RMI を使ったアプリケーションで、これらの新しいソケットファクトリインタフェースを利用するために、UnicastRemoteObject と java.rmi.activation.Activatable. の両方に、いくつかの新しいコンストラクタおよび exportObject メソッドが追加されました。これらのコンストラクタおよびメソッドは、クライアントおよびサーバーソケットファクトリを追加されたパラメータとして利用します。
この新しいコンストラクタまたは exportObject メソッドのどちらかによって (RMIClientSocketFactory および RMIServerSocketFactory パラメータを使って) エクスポートされるリモートオブジェクトは、RMI ランタイムにより特別に扱われます。リモートオブジェクトの存続期間中、ランタイムは、ServerSocket を作成してリモートオブジェクトへの着呼を受け入れるために、カスタムの RMIServerSocketFactory を使用し、Socket を作成してクライアントをリモートオブジェクトに接続するために、カスタムの RMIClientSocketFactory を使用します。
カスタムソケットファクトリとともにエクスポートされるリモートオブジェクトのスタブおよびスケルトン内で使われる RemoteRef および ServerRef の実装は、それぞれ UnicastRef2 および UnicastServerRef2 です。UnicastRef 型のワイヤーの表現では、接続するための「エンドポイント」の表現に、UTF 形式のホスト名文字列とそのあとに整数のポート番号だけを使用していました。UnicastRef2 型のワイヤーの表現には、これとは異なる表現が含まれています。UnicastRef2 では、エンドポイントのワイヤー表現は、残りのエンドポイント表現の内容を指定する形式のバイト (将来のエンドポイント表現の拡張用)、およびそれに続く指定された形式のデータによって構成されています。現在のところ、データは、UTF 形式のホスト名、ポート番号、および (エンドポイントの形式バイトによって指定されたときは) クライアントがこのエンドポイントでリモートオブジェクトへのソケット接続を生成するために使う RMIClientSocketFactory オブジェクトの直列化表現で構成されます。エンドポイントの表現には、リモートオブジェクトのエクスポート時に指定された RMIServerSocketFactory オブジェクトは含まれません。
UnicastRef2 型の参照を使って呼び出しが行われた場合、ランタイムは、指定されたリモートオブジェクトへの接続用ソケットの作成時に、エンドポイントの RMIClientSocketFactory オブジェクトの createSocket メソッドを使います。また、ランタイムが特定のリモートオブジェクトに対して DGC「dirty」および「clean」呼び出しを実行する際に、リモート参照で指定されたのと同じ RMIClientSocketFactory オブジェクトから生成された接続を使って、リモート JVM 上の DGC を呼び出す必要があります。サーバー側の DGC 実装は、この処理が正しく行われたことを確認する必要があります。
カスタムソケットファクトリを引数としてとらない UnicastRemoteObject 上の古いコンストラクタまたはメソッドを使ってエクスポートされたリモートオブジェクトでは、以前と同様に、UnicastRef および UnicastServerRef 型の RemoteRef および ServerRef が使われます。このようなオブジェクトには、エンドポイントの古いワイヤー表現である、UTF 形式のホスト文字列に続いてポート番号を指定する整数が使われます。これは、新しい 1.2 の機能を使わない RMI サーバーが、以前のバージョンの RMI クライアントと相互運用を可能にするためです。
RMISocketFactory クラスjava.rmi.server.RMISocketFactory クラスは、トランスポートがソケットを取得する方法を指定するインタフェースを提供します。次のクラスは、java.net パッケージの Socket および ServerSocket を使用します。
package java.rmi.server;
public abstract class RMISocketFactory
implements RMIClientSocketFactory, RMIServerSocketFactory
{
public abstract Socket createSocket(String host, int port)
throws IOException;
public abstract ServerSocket createServerSocket(int port)
throws IOException;
public static void setSocketFactory(RMISocketFactory fac)
throws IOException {...}
public static RMISocketFactory getSocketFactory() {...}
public static void setFailureHandler(RMIFailureHandler fh) {...}
public static RMIFailureHandler getFailureHandler() {...}
}
static メソッド setSocketFactory は、RMI がソケットを取得するためのソケットファクトリを設定します。アプリケーションが自身の RMISocketFactory のインスタンスのためにこのメソッドを呼び出せるのは 1 回だけです。アプリケーションの定義による RMISocketFactory の実装は、たとえば接続要求に対して事前にフィルタリングを行なって例外をスローするか、あるいは java.net.Socket または java.net.ServerSocket クラスの独自の拡張を返して、セキュアな通信チャネルを確保します。RMISocketFactory を設定できるのは、実行中のセキュリティーマネージャーがソケットファクトリの設定を許可している場合だけです。ソケットファクトリの設定が許可されていない場合には、SecurityException がスローされます。
static メソッド getSocketFactory は、RMI によって使用されるソケットファクトリを返します。ソケットファクトリが設定されていなければ、このメソッドは null を返します。
トランスポート層は、トランスポートでソケットの作成が必要になると、getSocketFactory メソッドが値を返した RMISocketFactory 上で createSocket と createServerSocket メソッドを呼び出します。例を示します。
RMISocketFactory.getSocketFactory().createSocket(myhost, myport)
createSocket メソッドは、指定されたホストとポートに接続されるクライアントソケットを作成するものです。createServerSocket は、指定されたポート上にサーバーソケットを作成するものです。
デフォルトトランスポートにおける RMISocketFactory の実装は、次のように HTTP を使ってファイアウォールを通り抜ける透過性のある RMI を提供します。
createSocket 上で、ファクトリは直接ソケットによる接続ができないホストに自動的に HTTP 接続を試みる。createServerSocket 上で、ファクトリはサーバーソケットを返し、新しく受け付けられた接続が HTTP POST 要求かを自動検出する。そうであれば、トランスポートへの要求の本体だけを透過的に伝え、出力を HTTP 応答として整形する。setFailureHandler メソッドは、サーバーソケットの作成に失敗すると失敗用ハンドラを RMI ランタイムにより呼び出されるように設定します。失敗用ハンドラはブール値を返して、リトライを行なってよいかどうかを示します。デフォルトの失敗用ハンドラは false を返し、デフォルト条件ではランタイムはソケット作成のリトライを行わないことを示します。
getFailureHandler メソッドは、ソケット作成失敗の現在のハンドラを返し、失敗用ハンドラが設定されていなければ、null を返します。
RMIServerSocketFactory インタフェースRMIServerSocketFactory API ドキュメントを参照してください。
RMIClientSocketFactory インタフェースRMIClientSocketFactory API ドキュメントを参照してください。