JavaTM Platform Debugger Architecture -
|
J2SE 5.0 では、コネクタと TransportService の実装を開発および配置できるように、新しいサービスプロバイダインタフェースが Java Debug Interface (JDI) に追加されています。TransportService は、5.0 の新しいクラスです。このクラスは、コネクタによって使用される基盤のトランスポートサービスを表し、デバッガとターゲット VM 間の接続の確立、および Java Debug Wire Protocol (JDWP) パケットの転送に使用されます。
JDI の新しいサービスプロバイダインタフェースに加え、J2SE 5.0 には JavaTM Debug Wire Protocol Transport Interface (jdwpTransport) という新しいトランスポートライブラリインタフェースも含まれています。これは、トランスポートライブラリの開発および配置を可能にするネイティブ (C/C++) インタフェースです。トランスポートライブラリは、debuggee 側の JDWP エージェントによってロードされ、デバッガとの接続の確立、およびデバッガと VM 間の JDWP パケットのトランスポートに使用されます。
このページでは、新しいインターフェースを使用する場合のシナリオについていくつか説明します。また、新しいコネクタとトランスポートの実装の開発および配置に関連するタスクの概要も説明します。
サービスプロバイダインタフェースとネイティブトランスポートインタフェースは、次のユーザーによって使用されることが想定されています。
これらのユーザーを考慮して、新しいインターフェースを使用する場合のいくつかのシナリオについて以下で説明します。
debuggee 側では、jdwpTransport インタフェースを実装することにより、新しいトランスポートのトランスポートライブラリを開発できます。デバッガの場合は、TransportService 実装を開発できます。TransportService 実装を配置すると、JDI VirtualMachineManager 実装によって自動的に AttachingConnector および ListeningConnector が作成され、ターゲット VM に対するリモートデバッグが可能になります。
これらの例の場合は、AttachingConnector 実装を開発できます。AttachingConnector 実装は、com.sun.jdi.connect.AttachingConnectors を拡張します。この実装を配置すると、VirtualMachineManager の attachingConnectors() メソッドによって返される接続コネクタのリストに表示されます。
この例では、IDE の実装者が jdwpTransport インタフェースを使用してトランスポートライブラリを開発します。この結果、debuggee では新しいトランスポートの使用が可能になります。デバッガ側では、IDE の実装者に選択肢があります。1 つのオプションは、TransportService 実装を開発および配置することです。このオプションでは、リモートデバッグに新しいトランスポートを使用できます。
また、IDE の実装者がトランスポートをカプセル化するコネクタ実装を作成することもできます。このオプションは、IDE の実装者が新しいコネクタ引数を追加したいときに適しています。たとえば、保護されたトランスポートを使う場合、IDE の実装者は、安全な接続を設定するために必要なキーストア、パスフレーズなどのオプションを指定するコネクタ引数を持つコネクタを使用したい場合があります。新しいコネクタが適している場合、IDE の実装者は、debuggee 側のトランスポートライブラリとデバッガ側のコネクタを開発します。コネクタのタイプは、実装者が選択できます。たとえば、debuggee を起動し、デバッガと debuggee 間の安全な接続を確立する LaunchingConnector を選択します。
各コネクタの実装には、すべてのコネクタメソッドの実装のほかに、public で引数なしのコンストラクタが必要です。コンストラクタは、初期化中に VirtualMachineManager によって呼び出されます。コンストラクタは無操作の場合や、トランスポートサービスのロードなどの初期化タスクを実行する場合があります。コンストラクタは、チェックされる例外をスローしません。このため、初期化中の問題はエラーまたはチェックされない例外としてスローされます。
コネクタで TransportService を使用する必要はありません。コネクタによっては、トランスポート以外の機構を使用してターゲット VM に接続する場合があります (シナリオの例のセクションでは、クラッシュダンプやハングプロセスに接続する AttachingConnectors の例を列挙)。TransportService 実装を使用するコネクタの場合、コネクタは TransportService 実装を直接参照するか、実行時に実装をロードすることができます。Sun が提供するトランスポートを利用するコネクタは、次のようなコードを使用してトランスポートサービスをロードする必要があります。
try { Class c = Class.forName("com.sun.tools.jdi.SocketTransportService"); ts = (TransportService)c.newInstance(); } catch (Exception x) { throw new Error(x); }
J2SE の実装には、Sun のソケットトランスポートサービスまたは共用メモリトランスポートサービスが含まれている必要がないため、この例では、トランスポートサービスが存在しない場合、エラーがスローされます。
コネクタのタイプが認識されていると仮定する場合、実装を開発するときに次のことに注意する必要があります。
VirtualMachine vm = Bootstrap.virtualMachineManager().createVirtualMachine(conn);
VirtualMachineManager には、LaunchingConnectors で使用するための createVirtualMachine の別の形式も含まれています。別の形式では、LaunchingConnector で debuggee を表す java.lang.Process を指定することができます。詳細については、com.sun.jdi.VirtualMachineManager の仕様を参照してください。
LaunchingConnector の例のソースコードを見るには、ここをクリックしてください。コネクタには、ターゲット VM で実行するクラスのクラス名を指定する
コネクタを配置するには、コネクタの完全修飾クラス名のリストを含むサービス設定ファイルと一緒にコネクタ実装のクラスを jar ファイルにパッケージ化する必要があります。その後、jar ファイルはシステムクラスローダーから可視の場所に配置されます。
META-INF/services/com.sun.jdi.connect.Connector というサービス設定ファイルが jar ファイルに含まれている必要があります。このファイルには、jar ファイルに含まれているコネクタの完全修飾クラス名のリストがあります。複数のコネクタ実装が同じ jar ファイルに含まれている場合があります。この場合、各コネクタのクラス名は別の行に記載されます。
SimpleLaunchingConnector という起動コネクタを配置したいと仮定します。このコネクタを配置するために、次のような META-INF/services/com.sun.jdi.connect.Connector ファイルを作成します。
# Our very simple launching connector SimpleLaunchingConnector
このサービス設定ファイルは、コネクタの実装を構成するクラスと一緒に jar ファイルにパッケージ化されます。
jar cf SimpleLaunchingConnector.jar \ META-INF/services/com.sun.jdi.connect.Connector \ SimpleLaunchingConnector.class
次に、jar ファイルはシステムクラスローダーから可視の場所にコピーされます。Sun の実装では、次のように拡張機能ディレクトリに jar ファイルがコピーされる可能性があります。
cp SimpleLaunchingConnector.jar $JAVA_HOME/lib/ext
ファイルが配置されると、デバッガの再起動時にコネクタが配置されます。つまり、VirtualMachineManager の allConnectors() メソッドによって返されるコネクタのリストに SimpleLaunchingConnector が含まれます。また、これは起動コネクタであるため、launchingConnectors() メソッドによって返される起動コネクタのリストにも表示されます。
トランスポートサービスを開発するには、次の 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 のインスタンスを返します。このため、Connection を実装して、デバッガが debuggee と JDWP パケットを交換できるようにする必要があります。
TransportService 実装の例として、Sun のソケットトランスポートのソースコードを見るには、ここをクリックしてください。この例は、参照用として提供されています。
ネイティブトランスポートライブラリを開発するには、jdwpTransport 仕様に記載されている各関数を実装する必要があります。関数のプロトタイプおよび定義は、${java_home}/include/jdwpTransport.h に定義されています。
トランスポートライブラリの実装者は、ダイナミックライブラリ (またはこれに相当するもの) への関数実装のコンパイルおよびリンクを行います。ライブラリは、トランスポートライブラリがロードされるときに JDWP エージェントから呼び出される jdwpTransport_OnLoad 関数をエクスポートします。一部の組み込み環境は、動的リンクをサポートしていません。そういった環境では、トランスポートライブラリに静的にリンクしなければならない場合があります。その場合、ライブラリのロードはありませんが、トランスポートライブラリを初期化し、環境ポインタを取得するために、jdwpTransport_OnLoad 関数が呼び出されます。
jdwpTransport 実装の例として、Sun のソケットトランスポートライブラリ (dt_socket) のソースコードを見るには、ここをクリックしてください。この例は、あくまでも参照用として提供されています。
TransportService は、コネクタと同様の方法で配置されます。TransportService を配置するには、TransportService の完全修飾クラス名のリストを含むサービス設定ファイルと一緒に TransportService 実装のクラスを jar ファイルにパッケージ化する必要があります。その後、jar ファイルはシステムクラスローダーから可視の場所に配置されます。
META-INF/services/com.sun.jdi.connect.spi.TransportService というサービス設定ファイルが jar ファイルに含まれている必要があります。 コネクタの配置と同様に、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
コネクタの配置と同様に、jar ファイルはシステムクラスローダーから可視の場所にコピーされます (たとえば、Sun の実装の場合は、拡張機能ディレクトリ $JAVA_HOME/lib/ext)。
TransportService は、ネイティブメソッドを使用する場合もあれば、ネイティブライブラリを必要とするほかの API に依存する場合もあります。その場合、ネイティブライブラリは、System.loadLibrary を使用してロードできる場所に存在する必要があります。
ネイティブトランスポートライブラリは、JDWP エージェントによってロードされます。このため、ネイティブトランスポートライブラリは、オペレーティングシステムの通常の実行時ライブラリ検索パス上に存在する必要があります。たとえば、Solaris または Linux システムの場合は、LD_LIBRARY_PATH 環境変数によって指定された検索パス上に存在する必要があります。
Copyright © 2004 Sun Microsystems, Inc.All Rights Reserved. コメントの送付先: Debugging Feedback |
|