機械翻訳について

Java Remote Method Invocation: 10 - RMIワイヤー・プロトコル


10.1 概要

RMIプロトコルは、ワイヤー上の形式のために、他に2つのプロトコルを利用します。Javaオブジェクト直列化プロトコルとHTTPプロトコルです。 オブジェクト直列化プロトコルは、呼出しと戻りのデータを整列化するために使用します。 HTTPプロトコルは、リモート・メソッド呼出しを「POST」し、条件が許せば戻り値を取得するために使用します。 それぞれのプロトコルは、別々の文法としてドキュメント化されます。 生成規則の非ターミナル・シンボルは、別のプロトコルが制御する規則を参照します(オブジェクト直列化またはHTTP)。 プロトコルの境界を越える場合は、それ以後の生成規則は、組み込まれたプロトコルを使用します。

文法表記についてのノート

10.2 RMIトランスポート・プロトコル

RMIのワイヤー形式は、Streamで表されます。 ここで採用している用語は、クライアントからみたものです。 Outは出力メッセージを示し、Inは入力メッセージを示します。 トランスポート・ヘッダーの内容は、オブジェクト直列化を使用した形式ではありません

Stream:
    Out
    In

RMIの入力と出力ストリームは対になっています。 Outストリームには、対応するInストリームがあります。 文法内のOutストリームは、ソケット(クライアントのパースペクティブから)の出力ストリームにマップされます。 Inストリーム(文法で)は、対応するソケットの入力ストリームとペアになります。 出力ストリームと入力ストリームは対になっているので、入力ストリームで必要になるヘッダー情報は、プロトコルを認識できたかどうかの確認のみです。それ以外のヘッダー情報(マジック番号やバージョン番号)は、ストリーム対のコンテキストに含めることが可能です。

10.2.1出力ストリームの形式

RMIの出力ストリームは、トランスポートHeader情報と、続いて一連のMessagesで構成されます。 交互に出力ストリームはHTTPプロトコルに組み込まれた呼出しを含めることができます。

Out:
    Header Messages
    HttpMessage

Header:
    0x4a 0x52 0x4d 0x49 Version Protocol

Version:
    0x00 0x01

Protocol:
    StreamProtocol
    SingleOpProtocol

StreamProtocol:
    0x4b

SingleOpProtocol:
    0x4c

Messages:
    Message
    Messages Message

Messagesは、Protocolで指定された特定のプロトコル内でラップされます。 SingleOpProtocolの場合、Headerの後にはMessageが1つのみ存在し、Messageがラップされる追加データは存在しません。 SingleOpProtocolは、単一のリクエストおよびレスポンスを超える相互作用は不可能なHTTPリクエストに埋め込まれた呼出しに使用されます。

StreamProtocolの場合、サーバーはプロトコルのサポートを確認するバイト0x4eで応答する必要があり、サーバーが確認できるホスト名とポート番号を含むEndpointIdentifierがクライアントによって使用されています。 この情報を使ってクライアントは、セキュリティ上の理由でできない場合もありますが、自分のホスト名を知ることができます。 クライアントは、接続を受け入れるためにクライアントのデフォルト・エンドポイントを含む別のEndpointIdentifierで応答する必要があります。

StreamProtocolの場合、このエンドポイント・ネゴシエーションの後、Messagesは、データの追加のラッピングなしで出力ストリームを介して送信されます。

出力メッセージには3つのタイプがあります: CallPingおよびDgcAck Callは、メソッド呼出しをエンコードします。 Pingは、リモート仮想マシンの有効性をテストするためのトランスポート・レベルのメッセージです。 DgcAckは、サーバーからの戻り値のリモート・オブジェクトがクライアントによって受信されたことを示す、サーバーの分散ガベージ・コレクタに送信される確認です。

Message:
    Call
    Ping
    DgcAck

Call:
    0x50 CallData

Ping:
    0x52

DgcAck:
    0x54 UniqueIdentifier

ノート: 廃止されたProtocol MultiplexProtocol (0x4d)は、Java SE 9で削除されました。

10.2.2入力ストリームの形式

現在3つのタイプの入力メッセージがあります: ReturnDataHttpReturnおよびPingAck ReturnDataは、"normal" RMIコールの結果です。 HttpReturnは、HTTPプロトコルに埋め込まれた起動からの戻り値です。 PingAckは、Pingメッセージの確認です。

In:
    ProtocolAck Returns
    ProtocolNotSupported
    HttpReturn

ProtocolAck:
    0x4e

ProtocolNotSupported:
    0x4f

Returns:
    Return
    Returns Return

Return:
    ReturnData
    PingAck

ReturnData:
    0x51 ReturnValue

PingAck:
    0x53

10.3 RMIによるオブジェクト直列化の使用

RMI呼出しにおける呼び出しと戻りのデータは、Javaオブジェクト直列化プロトコルに従って整形されます。 各メソッドの呼出しのCallDataは、ObjectIdentifier (コールのターゲット)、Operation (呼び出されるメソッドを表す数値)、Hash (クライアント・スタブとリモート・オブジェクト・スケルトンが同じスタブ・プロトコルを使用していることを検証する番号)、およびコールの0以上のArgumentsのリストを含むJavaオブジェクト出力ストリームに書き込まれます。

JDK1.1スタブ・プロトコルでは、Operationrmic,によって割り当てられたメソッド番号を表し、Hashはスタブのインタフェース・ハッシュであるスタブ/スケルトン・ハッシュです。 Java 2スタブ・プロトコル(Java 2スタブは、-v1.2オプションとrmicを使用して生成されます)の時点では、Operationの値は -1で、Hashはコールするメソッドを表すハッシュです。 ハッシュについては、セクション"RemoteRefインタフェース"で説明しています。

CallData:
    ObjectIdentifier Operation Hash Arguments[opt]
    ObjectIdentifier:
    ObjectNumber UniqueIdentifier

UniqueIdentifier:
    Number Time Count

Arguments:
    Value
    Arguments Value

Value:
    Object
    Primitive

RMIコールのReturnValueは、通常または例外の戻り値を示すリターン・コード、戻り値(必要に応じてDGCAckの送信に使用)にタグを付けるUniqueIdentifier、その後に戻り結果で構成されます: 戻されたValueまたはスローされたExceptionのいずれか。

ReturnValue:
    0x01 UniqueIdentifier Value[opt]
    0x02 UniqueIdentifier Exception

ノート: ObjectIdentifierUniqueIdentifier,およびEndpointIdentifierは、デフォルトの直列化では書き出されませんが、それぞれ独自の特殊なwriteメソッド(これはオブジェクトの直列化で使用されるwriteObjectメソッドではありません)を使用します。識別子の各タイプのwriteメソッドは、そのコンポーネント・データを出力ストリームに連続して追加します。

10.3.1クラスの注釈およびロード

RMIは、ObjectOutputStreamannotateClassメソッドおよびObjectInputStreamresolveClassメソッドをそれぞれオーバーライドします。 各クラスには、コード・ベースのURL (クラスをロードする元の場所)を使用して注釈が付けられています。 annotateClassメソッドでは、クラスをロードしたクラス・ローダーに対し、そのクラス・ローダーのコード・ベースのURLを問い合わせます。 クラス・ローダーが非nullで、非nullコード・ベースを持っている場合は、そのコード・ベースは、ObjectOutputStream.writeObjectメソッドを使用してストリームに書き込まれます。それ以外の場合は、writeObjectメソッドを使用して、ストリームにnullが書き込まれます。 ノート: 最適化のため、「java」パッケージ内のクラスには、ノートが付けられません。これは、これらのクラスは受信側が常に利用できるからです。

クラスの注釈は、直列化復元中にObjectInputStream.resolveClassメソッドを使用して解決されます。 resolveClassメソッドは、最初にObjectInputStream.readObjectメソッドを使用して、注釈を読み取ります。 注釈(コード・ベースURL)がnullでない場合は、そのURLのクラス・ローダーを取得して、クラスをロードしようとします。

10.4 RMIによるHTTP POSTプロトコルの使用

プロキシ経由のファイアウォール経由のRMI呼び出しの実装は、JDK 9では削除されています。

10.5 RMIのアプリケーション固有の値

この表では、RMIで使用されるアプリケーション固有の値を表現する非ターミナル・シンボルを示します。 この表では、それぞれのシンボルがそれぞれの持つ型に対応しています。 各シンボルは、それが埋め込まれるプロトコルを使用して整形されます。

シンボル type
Count short
Exception java.lang.Exception
Hash long
Hostname UTF
Number int
Object java.lang.Object
ObjectNumber long
Operation int
PortNumber int
Primitive byte, int, short, long ...
Time long