機械翻訳について

Java Platform Debugger Architecture -サービス・プロバイダ・インタフェース

Java Platform Debugger Architecture -サービス・プロバイダ・インタフェース

Java Debug Interface (JDI)のサービス・プロバイダ・インタフェースを使用すると、ConnectorTransportServiceの実装を開発および配備できます。 TransportServiceクラスは、Connectorで使用される基盤のトランスポート・サービスを表し、デバッガとターゲットVM間の接続の確立、およびJava Debug Wire Protocol (JDWP)パケットのトランスポートに使用されます。

JDIのサービス・プロバイダ・インタフェースに加えて、JDKにはJava Debug Wire Protocol Transport Interface (jdwpTransport)と呼ばれるトランスポート・ライブラリ・インタフェースも含まれています。 これは、トランスポート・ライブラリの開発および配置を可能にするネイティブ(C/C++)インタフェースです。 トランスポート・ライブラリは、debuggee側のJDWPエージェントによってロードされ、デバッガへの接続の確立、およびデバッガとVM間のJDWPパケットのトランスポートに使用されます。

このページでは、新しいインタフェースが使用される可能性のあるいくつかのシナリオについて説明します。 また、新しいコネクタとトランスポートの実装の開発および配置に関連するタスクの概要についても説明します。


シナリオの例

サービス・プロバイダ・インタフェースとネイティブ・トランスポート・インタフェースは、次のユーザーによって使用されることが想定されています。

これらのユーザーを考慮して、新しいインタフェースを使用する場合のいくつかのシナリオについて説明します。


Connectorの開発

Connectorの開発には、LaunchingConnectorAttachingConnectorまたはListeningConnectorの具体的な実装の作成が含まれます。

すべてのConnector実装には、すべてのConnectorメソッドの実装に加えて、引数を取らないパブリック・コンストラクタが必要です。 コンストラクタは、初期化中にVirtualMachineManagerによってコールされます。 コンストラクタは無操作の場合や、トランスポート・サービスのロードなどの初期化タスクを実行する場合があります。 コンストラクタはチェックされた例外をスローしないため、初期化中の問題は、Errorまたはその他の未チェックの例外としてスローする必要があります。

TransportServiceを使用するには、Connectorsは必要ありません。 Connectorsの中には、トランスポート(「シナリオの例」セクションに、クラッシュ・ダンプまたはハングしたプロセスに接続するAttachingConnectorsの例を示します)以外のメカニズムを使用してターゲットVMに接続できるものがあります。 TransportService実装を使用するConnectorsの場合、ConnectorTransportService実装を直接参照するか、実行時に実装をロードできます。 Oracleが提供するトランスポートを使用しようとするConnectorは、次のようなコードを使用してトランスポート・サービスをロードするようにしてください。

try {
    Class<?> c = Class.forName("com.sun.tools.jdi.SocketTransportService");
    ts = (TransportService)c.newInstance();
} catch (Exception x) {
    throw new Error(x);
}

Java SE実装には、Oracleのソケットまたは共有メモリー・トランスポート・サービスの実装を含める必要はありません。前述の例では、トランスポート・サービスが存在しない場合にErrorがスローされます。

Connectorのタイプがわかっている場合、実装の開発時に次のアイテムに注意してください:

    VirtualMachine vm = Bootstrap.virtualMachineManager().createVirtualMachine(conn);
\
\
The `VirtualMachineManager` also involves another form of the
`createVirtualMachine` method for use by `LaunchingConnector` instances.
The other form allows the `LaunchingConnector` to specify the
`java.lang.Process` that represents the debuggee. See the specification for
`com.sun.jdi.VirtualMachineManager` for further details.

Connectorの配備

Connectorをデプロイするには、Connector実装のクラスを、Connectorの完全修飾クラス名をリストするサービス構成ファイルとともにjarファイルにパッケージ化する必要があります。 その後、jarファイルはシステム・クラス・ローダーから可視の場所に配置されます。

jarファイルに含める必要があるサービス構成ファイルの名前は、META-INF/services/com.sun.jdi.connect.Connectorです。 このファイルには、jarファイルに含まれるConnectorの完全修飾クラス名がリストされます。 複数のConnector実装を同じjarファイルに含めることができ、その場合、各Connectorのクラス名が別の行にリストされます。

SimpleLaunchingConnectorという起動コネクタをデプロイするとします。 これをデプロイするには、次のようなファイルMETA-INF/services/com.sun.jdi.connect.Connectorを作成します:

# A very simple launching connector
SimpleLaunchingConnector

このサービス構成ファイルは、コネクタの実装を構成するクラスと一緒にjarファイルにパッケージ化されます。

jar cf SimpleLaunchingConnector.jar \
    META-INF/services/com.sun.jdi.connect.Connector \
    SimpleLaunchingConnector.class

次に、jarファイルはシステム・クラス・ローダーから可視の場所にコピーされます。

デプロイすると、デバッガの再起動時にデバッガによってConnectorが検索されます。 つまり、SimpleLaunchingConnectorは、VirtualMachineManagerallConnectors()メソッドによって返されるConnectorsのリストに含まれます。 また、これは起動コネクタであるため、launchingConnectors()メソッドによって返される起動コネクタのリストにも表示されます。


TransportServiceの開発

トランスポート・サービスを開発するには、次の2つのコンポーネントを開発する必要があります。

トランスポート・サービスの開発には、トランスポートと基盤になる通信プロトコルについての高度な知識が必要です。 トランスポート・サービスは、JDWPを基盤となる通信プロトコルにバインドします。 提供するサービスは信頼性が高く、JDWPパケットはデバッガとdebuggeeの間で重複したりデータが失われることなく、交換されます。 パケットを信頼性の高い方法で交換しなければならないことを考えると、トランスポート・サービスは、基盤となる通信プロトコルが提供するサービスを超えるプロトコル・サポートを提供するべきです。 たとえば、処理されていない信頼性の低いシリアル接続を介したデバッグが必要な場合、トランスポート・サービスの実装者は、エラーの検出と回復を実装に組み込んで、デバッガとdebuggeeの間でJDWPパケットを信頼性の高い方法で転送できるようにする必要があります。

トランスポートと基盤の通信プロトコルの詳細を理解したら、次のステップは、次のことを考慮します。

    /dev/ttya;9600,1

前述の解決後、TransportServiceの作成には、com.sun.jdi.connect.spi.TransportServiceの拡張と実装の提供が含まれます。 attachメソッドおよびacceptメソッドは、com.sun.jdi.connect.spi.Connectionのインスタンスを返すため、デバッガがJDWPパケットをデバッグ先と交換できるように、Connectionの実装が必要です。

ネイティブ・トランスポート・ライブラリを開発するには、jdwpTransport仕様に記載されている各関数を実装する必要があります。 関数のプロトタイプと定義は、${java_home}/include/jdwpTransport.hで定義されています。

トランスポート・ライブラリの実装者は、関数実装をコンパイルし、ダイナミック・ライブラリ(またはこれに相当するもの)にリンクします。 ライブラリは、トランスポート・ライブラリのロード時にJDWPエージェントが呼び出す関数jdwpTransport_OnLoad関数をエクスポートします。 一部の組込み環境は、動的リンクをサポートしていません。そういった環境では、トランスポート・ライブラリに静的にリンクしなければならない場合があります。 その場合、ライブラリのロードは行われませんが、jdwpTransport_OnLoad関数は、トランスポート・ライブラリを初期化して環境ポインタを取得するためにコールされます。


TransportServiceの配備

TransportServiceは、Connectorと同様の方法でデプロイされます。 TransportServiceをデプロイするには、TransportService実装のクラスを、TransportServiceの完全修飾クラス名をリストするサービス構成ファイルとともにjarファイルにパッケージ化する必要があります。 その後、jarファイルはシステム・クラス・ローダーから可視の場所に配置されます。

jarファイルに含める必要があるサービス構成ファイルの名前は、META-INF/services/com.sun.jdi.connect.spi.TransportServiceです。 Connectorデプロイメントによると、jarファイルに複数の実装が含まれている場合に、構成ファイルで複数のトランスポート・サービス実装のクラス名をリストできます。

トランスポート・サービスcom.sun.SerialTransportServiceの場合、サービス構成ファイルは次のようになります :

# Serial line transport
com.foo.SerialTransportService

このサービス構成ファイルは、実装を構成するクラスと一緒にjarファイルにパッケージ化されます。 この例では、実装に多数のクラスが含まれると仮定します。

jar cf SerialTransportService.jar \
    META-INF/services/com.sun.jdi.connect.spi.TransportService \
    com/foo/SerialTransportService.class \
    com/foo/SerialConnection.class \
    com/foo/SerialCapabilities.clas \
    com/foo/SerialIO.class \
    com/foo/SerialProtocol.class

Connectorsのデプロイメントに従って、jarファイルがシステム・クラス・ローダーに表示されるロケーションにコピーされます。

TransportServiceは、ネイティブ・メソッドを持つか、ネイティブ・ライブラリを必要とする他のAPIに依存する場合があります。 その場合、ネイティブ・ライブラリは、System.loadLibraryを使用してロードできるロケーションである必要があります。

ネイティブ・トランスポート・ライブラリは、JDWPエージェントによってロードされます。 このため、ネイティブ・トランスポート・ライブラリは、オペレーティング・システムの通常の実行時ライブラリ検索パス上に存在する必要があります。 たとえば、Linuxシステムでは、LD_LIBRARY_PATH環境変数で指定された検索パスにある必要があります。