JPDA内では、デバッガ・アプリケーションはJava Debug Interface (JDI)インタフェースとコネクタ抽象を使用してターゲットVMへの接続を確立します。デバッガ・アプリケーションによって使用されるコネクタは、トランスポートをカプセル化します。ターゲットVMでは、デバッガとの通信にJava Debug Wire Protocolをサポートするエージェントが使用されます。このエージェント(ターゲットVMに組み込むか、実行時ライブラリからロード可能)は、デバッガと通信するためにトランスポートをカプセル化します。
TCP/IPに基づくソケット・トランスポートと共用メモリー・トランスポートの2つのトランスポート実装は、リファレンス実装とともに出荷されます。仕様では、特定のトランスポートの実装を必要としません。この実装とともに提供されるトランスポートのほかにも、アーキテクチャに含まれるサービス・プロバイダ・インタフェースを使用して、別のトランスポートを開発および配備できます。
コマンドと応答パケットは、JDWPトランスポート・インタフェースを使用して、JDWP仕様に従ってストリームに書き込まれます。JDWPを介して多数の小さなパケットを送信できるため、TCP_NO_DELAYソケット・オプションにより、小さなパケットが送信される前にソケット実装によってバッファされる場合に発生する可能性のある遅延を回避することによって、一部のソケット実装でパフォーマンスを向上させることができます。可能な場合は未送信のデータが送信されるように、ソケットは適切に閉じられます。
ソケット・トランスポートは、dt_socketという一意の文字列で識別されます。この名前は、ターゲットVMを呼び出すときに、ソケット・トランスポートを選択するために使用できます。デバッガ・アプリケーションでは、対応するコネクタによってソケット・トランスポートがカプセル化されます。
クライアントがサーバーに接続しているコンテキストでは、ソケット・トランスポート・アドレスの形式は、「<name>:<port>」になります。<name>はホスト名です。また、<port>は接続または待機しているソケット・ポート番号です。サーバーがクライアントの接続を待機しているコンテキストでは、アドレスはポート番号だけで構成されます(ホスト名は明示されません)。
共用メモリー・トランスポートは、dt_shmemという一意の文字列で識別されます。この名前は、ターゲットVMを呼び出すときに、ソケット・トランスポートを選択するために使用できます。デバッガ・アプリケーションでは、対応するコネクタによって共用メモリー・トランスポートがカプセル化されます。
共用メモリーのトランスポート・アドレスは、Microsoft Windowsのファイル・マッピング・オブジェクトの名前として使用できます。この名前の文字列には、バックスラッシュを除く任意の文字を含めることができます。
実装されるコネクタをユーザーが選択および構成できるように、JDIクライアント・アプリケーションを作成することもできますが、特定のコネクタに関する情報をデバッガに組み込んでおくと、ユーザーが使いやすい構成になります。JPDAで提供されているJDBの実装例では、この方法が採用されています。
JDIリファレンス実装では、使用可能なトランスポートの種類および接続モード(起動、待機、および接続)に対応するいくつかのコネクタが提供されています。それらのコネクタについて、このあとのセクションで説明します。これらのコネクタのリストは、JDIメソッドVirtualMachineManager.allConnectors()によって返されます。また、各接続コネクタ、待機コネクタ、および起動コネクタは、対応するVirtualMachineManagerメソッドattachingConnectors()、listeningConnectors()、およびlaunchingConnectors()によって返されるリストに含まれます。
このコネクタは、「com.sun.jdi.CommandLineLaunch」という名前で一意に識別されます。
名前 | 必須 | デフォルト値 | 説明 |
---|---|---|---|
home | いいえ | 現在のjava.homeプロパティ値 | ターゲットVMの呼出しに使用されるJava Runtime Environment (JRE)の場所。 |
options | いいえ | "" | VMを呼び出すために使用する標準のデバッグ・オプションを含むオプション。 |
main | はい | "" | デバッグするアプリケーションのメイン・クラスおよびコマンド行の引数。 |
suspend | いいえ | true | メイン・クラスがロードされる直前にターゲットVMが中断される場合はtrue、そうでない場合はfalse。 |
quote | はい | "\"" | コマンド行上で、空白で区切られたテキストを結合するときに使用する文字。 |
vmexec | はい | java | VM起動用ウィンドウの実行可能ファイル。デバッグ時には、javawまたはjava_gに変更できる(それらの起動用ウィンドウが使用可能な場合)。 |
このコネクタは、「com.sun.jdi.RawCommandLineLaunch」という名前で一意に識別されます。
名前 | 必須 | デフォルト値 | 説明 |
---|---|---|---|
command | はい | "" | デバッグするアプリケーションからターゲットVMを呼び出すときに使用するコマンド行全体。 |
address | はい | "" | 新しく起動されたターゲットVMの接続を待機するトランスポート・アドレス。この値は、通常はrawコマンドの引数として使用される。ただし、接続先のトランスポート・アドレスを、ターゲットVMで独自に識別できる場合は必須ではない。 |
quote | はい | "\"" | コマンド行上で、空白で区切られたテキストを結合するときに使用する文字。 |
このコネクタは、「com.sun.jdi.SocketAttach」という名前で一意に識別されます。
名前 | 必須 | デフォルト値 | 説明 |
---|---|---|---|
hostname | いいえ | ローカル・ホスト名 | 接続先のホスト・マシン名。 |
port | はい | "" | 接続先のhostマシン上のポート番号。 |
timeout | いいえ | "" | ターゲットVMへの接続時に使用するタイム・アウト(ミリ秒単位)。 |
このコネクタは、「com.sun.jdi.SharedMemoryAttach」という名前で一意に識別されます。
名前 | 必須 | デフォルト値 | 説明 |
---|---|---|---|
name | はい | "" | ターゲットVMが待機中の共用メモリーのトランスポート・アドレス。 |
timeout | いいえ | "" | ターゲットVMに接続するときに使用するタイム・アウト(ミリ秒単位) |
このコネクタでは、複数のターゲットVMからの接続を受け入れることができます。
このコネクタは、「com.sun.jdi.SocketListen」という名前で一意に識別されます。
名前 | 必須 | デフォルト値 | 説明 |
---|---|---|---|
port | いいえ | 一時的なポート番号(TCP/IPスタックによって割り当てられるポート) | 接続を待機するポート番号。 |
localAddress | いいえ | ホストに割り当てられるすべてのアドレス | ホストに割り当てられるIPアドレス |
timeout | いいえ | "" | ターゲットVMの接続を待機する間に使用するタイム・アウト(ミリ秒単位) |
このコネクタでは、複数のターゲットVMからの接続を受け入れることができます。
このコネクタは、「com.sun.jdi.SharedMemoryListen」という名前で一意に識別されます。
名前 | 必須 | デフォルト値 | 説明 |
---|---|---|---|
name | はい | "" | ターゲットVMの接続を待機する共用メモリーのトランスポート・アドレス。 |
timeout | いいえ | "" | ターゲットVMの接続を待機する間に使用するタイム・アウト(ミリ秒単位) |
名前 | 必須 | デフォルト値 | 説明 |
---|---|---|---|
pid | はい | "" | デバッグされるプロセスのプロセスID。 |
timeout | いいえ | "" | ターゲットVMへの接続時に使用するタイム・アウト(ミリ秒単位)。 |
名前 | 必須 | デフォルト値 | 説明 |
---|---|---|---|
core |
いいえ | core | デバッグするコア・ファイルのパス名 |
javaExecutable |
はい |
"" |
コア・ファイルを生成したJava実行可能ファイルのパス名。 |
名前 | 必須 | デフォルト値 | 説明 |
---|---|---|---|
pid | はい | "" | デバッグされるプロセスのプロセスID。 |
${JAVA_HOME}/bin/rmiregistry -J-Xbootclasspath/p:${JAVA_HOME}/lib/sa-jdi.jar
${JAVA_HOME}/bin/java \ -classpath ${JAVA_HOME}/lib/sa-jdi.jar \ sun.jvm.hotspot.jdi.SADebugServer \ <pid> \ [uniqueID]
または
${JAVA_HOME}/bin/java \ -classpath ${JAVA_HOME}/lib/sa-jdi.jar \ sun.jvm.hotspot.jdi.SADebugServer \ <pathname to the java executable that produced the core file>\ <pathname of the corefile to debug> \ [uniqueID]
上記の2つの手順の代わりに、jsadebugd (Solaris、Linux、またはMac OS XまたはWindows)コマンドを使用して、リモート・マシンでRMIレジストリとデバッグ・サーバーを起動する方法もあります。
「uniqueID」はオプションの文字列です。同じマシンで複数のデバッグ・サーバーを同時に実行する場合は、各サーバーに異なる「uniqueID」文字列を指定する必要があります。
上の例のJAVA_HOMEには、デバッグ対象で使用されるバージョンと同じビット・サイズ(つまり32ビットまたは64ビット)および同じバージョン(5.0、5.1など)のJavaインストールのパス名が含まれていなければなりません。ただし、デバッガのビット・サイズとバージョンは同じである必要はありません。
デバッグされるプロセスが、デバッグ・モードで(つまり、-agentlib:jdwpまたは -Xrunjdwpを使用して)開始されている必要はありません。 プロセスがハング・アップしても問題ありません。プロセスは、デバッグ・サーバーの接続時に中断されます。プロセスに接続されているデバッグ・サーバーを(^Cまたはほかの方法で)終了すると、デバッグ対象プロセスは再開されます。コア・ファイルに複数のデバッグ・サーバーを接続することはできますが、プロセスに接続できるデバッグ・サーバーは1つだけです。
このコネクタでは、同じデバッグ・サーバーに複数のデバッグ・セッションを接続できます。
このコネクタは、「sun.jvm.hotspot.jdi.SADebugServerAttachingConnector」という名前で一意に識別されます。
名前 | 必須 | デフォルト値 | 説明 |
---|---|---|---|
debugServerName | はい | "" | デバッグ・サーバーが実行されているマシンのIPアドレスまたは名前。このマシンに複数のデバッグ・サーバーが含まれている場合、この名前は、 uniqueID@IPAddress または uniqueID@hostname という形式である必要があります。ここで、「uniqueID」は対応するデバッグ・サーバーを起動するために使用される文字列です。 |
OracleのVM実装には、デバッグ用のJDWPエージェントをロードするコマンド行オプションが必要です。JDWPエージェントをロードしたり、そのオプションを指定したりするために-agentlib:jdwpオプションが使用されます。
-agentlib:jdwpオプションは、次のように指定されます。
-agentlib:jdwp=<name1>[=<value1>],<name2>[=<value2>]...
または
-Xrunjdwp:<name1>[=<value1>],<name2>[=<value2>]...
名前 | 必須 | デフォルト値 | 説明 |
---|---|---|---|
help | いいえ | なし | 簡単なヘルプ・メッセージを出力してVMを終了する。 |
transport | はい | なし | デバッガ・アプリケーションに接続するときに使用するトランスポートの名前。 |
server | いいえ | "n" | 「y」の場合は、デバッガ・アプリケーションへの接続を待機する。そうでない場合は、指定されたアドレスのデバッガ・アプリケーションに接続する。
「y」が指定されているときにアドレスが指定されていない場合は、デバッガ・アプリケーションを待機するトランスポート・アドレスを選択し、標準出力ストリームにそのアドレスを出力する。 |
address | server=n の場合は、はい。それ以外の場合は、いいえ |
"" | 接続用のトランスポート・アドレス。server=nの場合は、このアドレスのデバッガ・アプリケーションに対して接続する。server=yの場合は、このアドレスで接続を待機する。 |
timeout | いいえ | "" | server=yの場合は、デバッガからの接続を待機するときに使用するタイム・アウト(ミリ秒単位)を指定する。server=nの場合は、デバッガへの接続時に使用するタイム・アウト(ミリ秒単位)を指定する。一部のトランスポート実装では、タイムアウト・オプションが無視される場合がある。 |
launch | いいえ | なし | JDWPの初期化が完了したときに、この文字列に指定されたプロセスを起動する。このオプションは、「Just-In-Timeデバッグ」を行うときに、onthrowまたはonuncaught、あるいはその両方のオプションと組み合わせて使用する。「Just-In-Timeデバッグ」では、このVMで特定のイベントが発生したときにデバッガ・プロセスが起動する。
起動されるプロセスは、自身のウィンドウでは起動されない。ほとんどの場合、起動されるプロセスは小さなアプリケーションで、起動後にデバッガ・アプリケーションが自身のウィンドウで起動される。 この引数に指定した文字列には、空白で区切られた次の文字列が追加される。これらの文字列は、起動されたデバッガがこのVMとの接続を確立するために使われる。こうして生成された文字列が実行される。
|
onthrow | いいえ | なし | 特定のクラスの例外がこのVMにスローされるまで、JDWPライブラリの初期化を遅延する。例外クラス名は、パッケージで修飾されていなければならない。JDWPが初期化されたときに接続が確立されるため、この例外がスローされるまで接続は確立されない。 |
onuncaught | いいえ | "n" | 「y」の場合は、uncaught例外がこのVMにスローされるまで、JDWPライブラリの初期化を遅延する。JDWPが初期化されたときに接続が確立されるため、この例外がスローされるまで接続は確立されない。uncaught例外の定義については、JDI仕様のcom.sun.jdi.ExceptionEventを参照。 |
suspend | いいえ | "y" | 「y」の場合、VMStartEventは中断ポリシーがSUSPEND_ALLになる。「n」の場合、VMStartEventの中断ポリシーはSUSPEND_NONEになる。 |
JDIの起動コネクタは、Plug-inアプレットのデバッグには使用できません。
JDBでは、-attachオプションを指定すると、リファレンス実装の接続コネクタ(Microsoft Windows上では共用メモリー、SolarisおよびLinuxプラットフォーム上ではソケット)にアクセスできます。-listenオプションを指定すると、リファレンス実装の待機コネクタ(Microsoft Windows上では共用メモリー、SolarisおよびLinuxプラットフォーム上ではソケット)にアクセスできます。コマンド行にクラス名と引数を直接指定すると、コマンド行起動コネクタにアクセスできます。
たとえば、
jdb -attach myhost:8000
上のように入力すると、ソケット接続コネクタを使用して簡単にターゲットVMに接続できます(Solarisオペレーティング環境の場合)。
jdb Hello 1 2 3
上のように入力すると、コマンド行起動コネクタを使用して簡単にターゲットVMを起動できます。
ただし、JDBには -connectオプションも用意されています。これにより、コネクタ名と、任意の名前/値の引数ペアのセットを指定することによって任意のコネクタを処理できます。たとえば、上記の2つのコマンド行は、次のコマンド行と同じことです。
jdb -connect com.sun.jdi.SocketAttach:hostname=myhost,port=8000
jdb -connect "com.sun.jdi.CommandLineLaunch:main=Hello 1 2 3"
これらのコマンド行は、最初の例よりも複雑ですが、-connectオプションを指定すれば任意のコネクタを使用できます。これらの操作から、JDIデバッガでは、任意のコネクタを使用できることがわかります。また、よく使われるコネクタを使用するための簡単なインタフェースも提供されています。
JPDAに含まれているサービス・プロバイダ・インタフェースを使うと、コネクタやトランスポートの実装を開発および配置できます。これらのサービス・プロバイダ・インタフェースにより、デバッガや他のツール・ベンダーで新しいコネクタ実装を開発し、Oracleが提供するソケットおよび共用メモリー・トランスポートを超える別のトランスポート・メカニズムを提供できます。JDIのサービス・プロバイダ・インタフェースは、 com.sun.jdi.connect.spiパッケージで指定されます。
JDIのサービス・プロバイダ・インタフェースに加え、Oracleの実装には、Java Debug Wire Protocol Transport Interfaceと呼ばれるトランスポート・ライブラリ・インタフェースも含まれています。トランスポート・ライブラリは、ターゲットVMのJDWPエージェントによってロードされ、デバッガとの接続の確立、およびデバッガとVM間のJDWPパケットのトランスポートに使用されます。
サービス・プロバイダ・インタフェースに関する詳細は、「Java Platform Debugger Architecture - サービス・プロバイダ・インタフェース」のドキュメントを参照してください。