目次 | 前の項 目 | 次の項目 | Java Remote Method Invocation |
RMI のトランスポート層は通常、インターネット上のホストへ直接ソケットを開こうとします。しかし、多くのイントラネットはファイアウォールを備えているため これができません。このため、デフォルトの RMI トランスポートでは、これに代わる 2 種類の HTTP ベースの機構を備えて、ファイアウォールの内側にあるクライアントが、ファイアウォールの外側にあるリモートオブジェクト上のメソッドを呼び出せるように しています。この節で説明したように、HTTP ベースの機構は、RMI のトランスポート層が RMI 呼び出しに使用するもので、HTTP プロキシサーバによるファイアウォールだけに適用されます。
ファイアウォールの外側に到達できるように、トランスポート層はファイアウォール信任 HTTP プロトコルに、RMI 呼び出しを埋め込んでおきます。RMI 呼び出しのデータは、HTTP POST リクエストの本体として外側へ送り出され、返される情報も HTTP による応答本体の一部として組み込まれています。トランスポート層は、POST リクエストの形式を次の 2 つのいずれかの方法で整えます。
RMI トランスポートの実装には、java.rmi.server.RMISocketFactory
クラスの拡張が含まれます。このクラスは、クライアントソケットおよびサーバソケットが RMI 呼び出しを送受信するために使用する、デフォルトのリソースプロバイダです。このデフォルトソケットファクトリは、java.rmi.server.RMISocketFactory.getDefaultSocketFactory
メソッドにより取得できます。このデフォルトソケットファクトリは、次に説明する方法で透過的なファイアウォールトンネリング機構を備えたソケットを作り 出します。
- クライアントのソケットは、まず直接ソケット接続を試みます。直接ソケット接続 を試みた結果、
java.net.NoRouteToHostException
またはjava.net.UnknownHostException
がスローされると、クライアントソケットは自動的に、直接ソケットによってアクセスできないホストへの HTTP 接続を試みます。直接ソケット接続の結果、java.net.ConnectException
などのその他のjava.io.IOException
がスローされると、この実装は HTTP 接続を試行することができます。- サーバソケットは、新たに受け付けられた接続が HTTP の POST リクエストであるかどうかを自動的に検出します。HTTP POST リクエストの場合、リクエストの本体だけを示すソケットをトランスポートに返し、その出力を HTTP による応答の形式に整えます。
このようなデフォルト動作をするクライアント側ソケットは、ファクトリのjava.rmi.server.RMISocketFactory.createSocket
メソッドが提供します。このようなデフォルト動作をするサーバ側のソケットは、ファクトリのjava.rmi.server.RMISocketFactory.createServerSocket
メソッドが提供します。
クライアントは、java.rmi.server.disableHttp
プロパティをブール値true
に等しく設定して、RMI 呼び出しを HTTP リクエスト形式にパッケージできなくすることができます。
注 - ホスト名は、 ホストの IP アドレスとして指定されてはなりません。 ファイアウォールプロキシの中には、そのような形式のホスト名を転送しないものがあるためです。
サーバのプラットフォームとネットワーク環境によっては、サーバが実行中の Java
仮想マシンがこのような情報を利用できない場合があります。利用できないときは、ホストの完全修飾された名前はサーバがスタートする時点で java.rmi.server.hostname
プロパティとして指定されていなければなりません。
たとえば、次のコマンドでマシン chatsubo.javasoft.com
上の RMI サーバクラス ServerImpl
をスタートさせることができます。
java -Djava.rmi.server.hostname=chatsubo.javasoft.com ServerImpl
HTTP リクエストを介して送信された呼び出しは、プロキシによる転送の時間のずれを除いたとしても、直接ソケットを介した場合よりもはるかに遅くなります。ファイアウォールを通す場合、HTTP リクエストは一方向でしか開始できないため、クライアントは自分のリモートオブジェクトをファイアウォールの外側へエクスポートすることはできません。 これは、ファイアウォールの外側にあるホストが、内側にあるクライアントのメソッド呼び出しを開始できないためです。