接続および呼出しの詳細
目次
トランスポート
コネクタ
VM起動オプション
JDBとの接続
サービス・プロバイダ・インタフェース
トランスポート
Javaプラットフォーム・デバッガ・アーキテクチャ(JPDA) トランスポートは、デバッガと(「ターゲットのVM」)をデバッグする仮想マシンの間の通信メソッドです。 通信は接続指向です。一方の側はサーバーとして機能し、接続をリスニングします。もう一方の側はクライアントとして機能し、サーバーに接続します。 JPDAでは、デバッガ・アプリケーションまたはターゲットVMのどちらかをサーバーとして動作させることができます。 トランスポートを実装することによって、単一のコンピュータまたは別のコンピュータ、あるいはその両方で動作中のプロセス間で通信できるようになります。 接続を確立する場合、「移送アドレス」を使用して接続のエンドポイントを識別します。 トランスポート・アドレスの形式は、トランスポートのタイプに依存します。
JPDA内では、デバッガ・アプリケーションはJava Debug Interface (JDI)インタフェースとConnector
抽象化を使用して、ターゲットVMへの接続を確立します。 「コネクタ」の項を参照してください。 デバッガ・アプリケーションで使用されるConnector
は、トランスポートをカプセル化します。 ターゲットVMでは、Java Debug Wire Protocolをサポートするエージェントを使用してデバッガと通信します。 このエージェント(ターゲットVMに組み込むか、実行時ライブラリからロード可能)は、デバッガと通信するためにトランスポートをカプセル化します。
2つのトランスポート実装がリファレンス実装に付属しています: TCP/IPおよび共有メモリー・トランスポートに基づくソケット・トランスポート。 仕様では、特定のトランスポートの実装を必要としません。 アーキテクチャには、実装で提供されるトランスポートに加えて、追加のトランスポートを開発およびデプロイできるようにするサービス・プロバイダ・インタフェースが含まれています。 「サービス・プロバイダ・インタフェース」の項を参照してください。
ソケット・トランスポート
JPDAリファレンス実装は、Linux、macOSおよびMicrosoft Windowsプラットフォーム用のソケット・トランスポートを提供します。 ソケット・トランスポートを使用する場合は、デバッガ・アプリケーションとターゲットVMは、同じコンピュータ上に存在していても、異なるコンピュータ上に存在していてもかまいません。 ソケット・トランスポートでは、デバッガ・アプリケーションとターゲットVMの間でシングル・ストリームのTCP/IP接続が使用されます。 IPv4とIPv6の両方が、JDI側およびターゲットのVM側のソケット・トランスポートでサポートされています。
コマンドと応答パケットは、JDWPトランスポート・インタフェースを使用して、JDWP仕様に従ってストリームに書き込まれます。 JDWP経由で多数の小規模なパケットを送信できるため、TCP_NO_DELAYソケット・オプションは、ソケット実装が小さなパケットを送信する前にバッファリングした場合に発生する遅延を回避することで、一部のソケット実装のパフォーマンスを向上させることができます。 可能な場合は未送信のデータが送信されるように、ソケットは適切に閉じられます。
ソケット・トランスポートは、一意の文字列dt_socket
を使用して識別されます。 この名前は、ターゲットVMを呼び出すときに、ソケット・トランスポートを選択するために使用できます。 「VM起動オプション」の項を参照してください。 デバッガ・アプリケーション内では、ソケット・トランスポートをカプセル化する対応するConnector
が使用されます。
ソケット転送アドレスの形式は<host>:<port>
で、<host>
はホスト名またはIPアドレス(大カッコで囲むことができます)、<port>
はアタッチまたはリスニングするソケット・ポート番号です。 <host>
が空の場合は、ローカル・ループバック・アドレスが使用されます。 サーバーがクライアントの連結を待機しているコンテキストで<host>
と"*
"が等しい場合、サーバーはすべてのネットワーク・インタフェースでリスニングします。
共用メモリー・トランスポート
JPDAリファレンス実装では、ソケット・トランスポートに加えて、Windowsで共有メモリー・トランスポートを提供します。 共用メモリー・トランスポートでは、デバッガ・アプリケーションとターゲットVMの間のJDWPパケット交換に共用メモリー領域が使用されます。 共用メモリー・トランスポートを使用する場合は、デバッガ・アプリケーションとターゲットVMは同じコンピュータ上に存在しなければなりません。
共有メモリー・トランスポートは、一意の文字列dt_shmem
を使用して識別されます。 この名前は、ターゲットVMを呼び出すときに、ソケット・トランスポートを選択するために使用できます。 「VM起動オプション」の項を参照してください。 デバッガ・アプリケーション内では、共有メモリー・トランスポートをカプセル化する対応するConnector
が使用されます。
共有メモリー・トランスポート・アドレスは、Windowsファイル・マッピング・オブジェクト名として使用できる名前です。 この名前の文字列には、バックスラッシュを除く任意の文字を含めることができます。
コネクタ
コネクタとは、デバッガ・アプリケーション(JDIを対象にして作成されたもの)とターゲットVMの間の接続を確立するときに使用されるJDIの抽象化のことです。 JDIおよびコネクタはさまざまな組み合わせで実装できるため、各JDIでサポートされているトランスポートおよびVMと一致させることができます。 コネクタ・インタフェースは非常に一般的であり、様々なコネクタ実装でJDIを使用できます。 コネクタは、名前と値のペアのセットを使用して構成されます。 特定のコネクタには、異なる名前と値のペアを使用できます。
適切なJDIクライアント・アプリケーションを使用すると、ユーザーは存在する可能性のあるコネクタを選択して構成できますが、特定のコネクタに関する知識をデバッガに組み込んで、構成をより快適なユーザー・エクスペリエンスにすることができます。 JPDAで提供されているJDBの実装例では、この方法が採用されています。 「JDBとの接続」の項を参照してください。
JDIリファレンス実装には、使用可能なトランスポート・タイプおよび接続モード(起動、リスニングおよびアタッチ)にマップする複数のコネクタが用意されています。 それらのコネクタについて、このあとのセクションで説明します。 これらのコネクタを含むList
は、JDIメソッドVirtualMachineManager.allConnectors()
によって返されます。 また、各アタッチ、リスニングおよび起動コネクタは、対応するVirtualMachineManager
メソッドattachingConnectors()
、listeningConnectors()
およびlaunchingConnectors()
によって返されるリストに含まれています。
コマンドライン起動コネクタ
デバッガ・アプリケーションは、このコネクタを使用して、「VM起動オプション」のセクションで説明したのと同じ呼び出しデバッグ・オプションをサポートする任意のVMを起動できます。 VMの起動および必要なデバッグ・オプションの指定の詳細は、コネクタによって制御されます。 このコネクタで使用される背後のトランスポートは、プラットフォームに依存しています。 Windowsでは、共有メモリー・トランスポートが使用されます。 LinuxおよびmacOSでは、ソケット・トランスポートが使用されます。
このコネクタは、com.sun.jdi.CommandLineLaunch
という名前で一意に識別されます。
名前 | 必須? | デフォルト値 | 説明 |
---|---|---|---|
home
|
no |
現在のjava.home プロパティ値
|
ターゲットVMの起動に使用されるJava Runtime Environment (JRE)のロケーション。 |
options
|
no | "" | VMを呼び出すために使用する標準のデバッグ・オプションを含むオプション。 「VM起動オプション」を参照してください。 |
main
|
yes | "" | デバッグするアプリケーションのメイン・クラスおよびコマンド行の引数。 |
suspend
|
no | true | メイン・クラスがロードされる直前にターゲットVMが中断される場合はtrue、そうでない場合はfalse。 |
quote
|
yes | """ | コマンド行上で、空白で区切られたテキストを結合するときに使用する文字。 |
vmexec
|
yes | java |
VM起動用ウィンドウの実行可能ファイル。 起動ツールが使用可能な場合は、これをjavaw またはデバッグ用のjava_g に変更できます。
|
RAWコマンドライン起動コネクタ
デバッガ・アプリケーションは、このコネクタを使用して任意のVMを起動できます。 コマンド行全体を指定する必要があり、いかなる方法でも編集されません。 指定したコマンド行でVMを起動する際の詳細は、コネクタによって制御されます。 このコネクタで使用される背後のトランスポートは、プラットフォームに依存しています。 Windowsでは、共有メモリー・トランスポートが使用されます。 LinuxおよびmacOSでは、ソケット・トランスポートが使用されます。
このコネクタは、com.sun.jdi.RawCommandLineLaunch
という名前で一意に識別されます。
名前 | 必須? | デフォルト値 | 説明 |
---|---|---|---|
command
|
yes | "" | デバッグ対象のアプリケーションでターゲットVMを呼び出すための完全なコマンド行。 |
address
|
yes | "" | 新しく起動されたターゲットVMの接続を待機するトランスポート・アドレス。 「トランスポート」の項を参照してください。 通常、この値はrawコマンド行引数の一部ですが、ターゲットVMが接続するトランスポート・アドレスを決定するほかの手段を持っている場合は必要ありません。 |
quote
|
yes | """ | コマンド行上で、空白で区切られたテキストを結合するときに使用する文字。 |
ソケット接続コネクタ
このコネクタは、現在動作中のターゲットVMにソケット・トランスポートを介して接続するときに、デバッガ・アプリケーションから使用できます。 このターゲットVMは、次の表で説明するこのコネクタの引数と対応するオプションで呼び出されたものである必要があります。 「VM起動オプション」の項では、必要なオプションについて説明します。
このコネクタは、com.sun.jdi.SocketAttach
という名前で一意に識別されます。
名前 | 必須? | デフォルト値 | 説明 |
---|---|---|---|
hostname
|
no | ローカル・ホスト名 | 接続先のホスト・マシン名。 |
port
|
yes | "" |
接続先のhost マシンのポート番号。
|
timeout
|
no | "" | ターゲットVMへの接続時に使用するタイム・アウト(ミリ秒単位)。 |
共用メモリー接続コネクタ
このコネクタは、共用メモリー・トランスポートを介して現在実行中のターゲットVMに接続するときに、デバッガ・アプリケーションから使用できます。 Windowsでのみ使用できます。 このターゲットVMは、次の表で説明するこのコネクタの引数と対応するオプションで呼び出されたものである必要があります。 「VM起動オプション」の項では、必要なオプションについて説明します。
このコネクタは、com.sun.jdi.SharedMemoryAttach
という名前で一意に識別されます。
名前 | 必須? | デフォルト値 | 説明 |
---|---|---|---|
name
|
yes | "" | ターゲットVMが待機している共有メモリー・トランスポート・アドレス。 「トランスポート」の項を参照してください。 |
timeout
|
no | "" | ターゲットVMに接続するときに使用するタイム・アウト(ミリ秒単位) |
ソケット待機コネクタ
このコネクタはデバッガ・アプリケーションで使用して、ソケット・トランスポートを介して個別に起動されたターゲットVMから接続を受け入れることができます。 このターゲットVMは、次の表で説明するこのコネクタの引数と対応するオプションで呼び出されたものである必要があります。 「VM起動オプション」の項では、必要なオプションについて説明します。
このコネクタでは、複数のターゲットVMからの接続を受け入れることができます。
このコネクタは、com.sun.jdi.SocketListen
という名前で一意に識別されます。
name | 必須? | デフォルト値 | description |
---|---|---|---|
port
|
no | 一時的なポート番号(TCP/IPスタックによって割り当てられるポート) | 接続をリスニングするポート番号 |
localAddress
|
no | ループバック・アドレス | 接続をリスニングするホスト名またはIPアドレス |
timeout
|
no | "" | ターゲットVMの接続を待機する間に使用するタイム・アウト(ミリ秒単位) |
共用メモリー待機コネクタ
このコネクタは、共用メモリー・トランスポートを介して個別に呼び出されたターゲットVMからの接続を受け入れるときに、デバッガ・アプリケーションから使用できます。 Windowsでのみ使用できます。 ターゲットVMは、次の表で説明するこのコネクタ引数と一致するオプションを使用して呼び出す必要があります。 「VM起動オプション」の項では、必要なオプションについて説明します。
このコネクタでは、複数のターゲットVMからの接続を受け入れることができます。
このコネクタは、com.sun.jdi.SharedMemoryListen
という名前で一意に識別されます。
名前 | 必須? | デフォルト値 | 説明 |
---|---|---|---|
name
|
yes | "" | ターゲットVMの接続を待機する共用メモリーのトランスポート・アドレス。 |
timeout
|
no | "" | ターゲットVMの接続を待機する間に使用するタイム・アウト(ミリ秒単位) |
プロセス接続コネクタ
このコネクタは、デバッガ・アプリケーションで使用して、「VM起動オプション」の項で説明されているserver=y
デバッグ・サブオプションで起動された現在実行中のターゲットVMにアタッチできます。 このターゲットVMは、Java SE 6以降である必要があります。
プロセス接続コネクタにトランスポートが関連付けられていません。 その代わりに、実際に接続されると、トランスポートが動的に決定されます。 このため、このコネクタのtransport().name()
メソッドはlocal
を返します。
このコネクタはcom.sun.jdi.ProcessAttach
という名前で一意に識別されます。
名前 | 必須? | デフォルト値 | 説明 |
---|---|---|---|
pid
|
yes | "" | デバッグされるプロセスのプロセスID。 |
timeout
|
no | "" | ターゲットVMへの接続時に使用するタイム・アウト(ミリ秒単位)。 |
VM起動オプション
このセクションでは、デバッグのためにVMを呼び出すために必要なオプションについて説明します。
Oracle VMの実装では、デバッグのためにJDWPエージェントをロードするためにコマンド行オプションが必要です。 -agentlib:jdwp
オプションは、JDWPエージェントにオプションをロードおよび指定するために使用します。
-agentlib:jdwp
オプションは次のように指定されます:
- -agentlib:jdwp=<suboptions>
- JDWPのJPDAリファレンス実装をロードする。 このライブラリはターゲットVMに存在し、Java Virtual Machine Tool Interface (JVM TI)およびJava Native Interface (JNI)を使用して対話します。 別のデバッガ・アプリケーションと通信するときは、トランスポートとJDWPプロトコルが使用される。 セクション「-agentlib:jdwpおよび-Xrunjdwpサブオプション」では、特定のサブオプションについて説明します。
-agentlib:jdwpおよび-Xrunjdwpサブオプション
-agentlib:jdwp
および-Xrunjdwp
オプションは、さらにサブオプションで修飾できます。 サブオプションは次のように指定されます:
-agentlib:jdwp=<name1>[=<value1>],<name2>[=<value2>]...
or
-Xrunjdwp:<name1>[=<value1>],<name2>[=<value2>]...
次の表では、使用可能なオプションについて説明します。
名前 | 必須? | デフォルト値 | 説明 |
---|---|---|---|
help
|
no | 該当なし | 簡単なヘルプ・メッセージを出力してVMを終了する。 |
transport
|
yes | none | デバッガ・アプリケーションに接続するときに使用するトランスポートの名前。 |
server
|
no | "n" |
「y」の場合は、デバッガ・アプリケーションへの接続を待機する。そうでない場合は、指定されたアドレスのデバッガ・アプリケーションに接続する。 「y」が指定されているときにアドレスが指定されていない場合は、デバッガ・アプリケーションを待機するトランスポート・アドレスを選択し、標準出力ストリームにそのアドレスを出力する。 「トランスポート」の項を参照してください。 |
address
|
server=n の場合はyes、それ以外の場合はno
|
"" |
接続用のトランスポート・アドレス。 server=n の場合、このアドレスでデバッガ・アプリケーションへのアタッチを試みます。 server=y の場合、このアドレスで接続を待機します。 「トランスポート」の項を参照してください。
|
timeout
|
no | "" |
server=y の場合、デバッガがアタッチするまで待機するタイムアウトをミリ秒単位で指定します。 server=n で、デバッガにアタッチするときに使用するタイムアウトをミリ秒単位で指定します。 一部のトランスポート実装では、タイムアウト・オプションが無視される場合がある。
|
launch
|
no | none |
JDWPの初期化が完了したときに、この文字列に指定されたプロセスを起動する。 このオプションは、 起動されるプロセスは、自身のウィンドウでは起動されない。 ほとんどの場合、起動されるプロセスは小さなアプリケーションで、起動後にデバッガ・アプリケーションが自身のウィンドウで起動される。 この引数に指定した文字列には、空白で区切られた次の文字列が追加される。 これらの文字列は、起動されたデバッガがこのVMとの接続を確立するために使われる。 こうして生成された文字列が実行される。
|
onthrow
|
no | none | 特定のクラスの例外がこのVMにスローされるまで、JDWPライブラリの初期化を遅延する。 例外クラス名はパッケージ修飾されていなければなりません。 JDWPが初期化されたときに接続が確立されるため、この例外がスローされるまで接続は確立されない。 |
onuncaught
|
no | "n" |
「y」の場合は、uncaught例外がこのVMにスローされるまで、JDWPライブラリの初期化を遅延する。 JDWPが初期化されたときに接続が確立されるため、この例外がスローされるまで接続は確立されない。 捕捉されない例外の定義については、com.sun.jdi.ExceptionEvent のJDI仕様を参照してください。
|
suspend
|
no | "y" | 「y」の場合、VMStartEventは中断ポリシーがSUSPEND_ALLになる。 「n」の場合、VMStartEventの中断ポリシーはSUSPEND_NONEになる。 |
includevirtualthreads
|
no | "n" | "y"の場合、デバッガが実行中のすべてのスレッドのリストをリクエストすると、仮想スレッドが含まれます。 デバッガにアタッチする前に作成された仮想スレッドを含めることはできません。 仮想スレッドの数が非常に多い場合、デバッガが圧倒される可能性があります。 "y"の場合、JDWPライブラリは、作成されたすべての仮想スレッドが停止するまで記憶し、その数が大きい場合はJDWPライブラリに圧倒される可能性があります。 |
さらに、dt_socket転送では、次のオプションがサポートされています: |
|||
allow
|
no | "*" |
server=yの場合、指定したアドレス/サブネットからの接続のみを許可します。 値は、"*" (アドレスからの接続を許可)またはプラス( リストの各エントリは次のように指定できます:
|
例
-agentlib:jdwp=transport=dt_socket,server=y,address=8000
-
ループバック・アドレスのみでポート8000のソケット接続をリスニングします。 メイン・クラスが(デフォルトでは
suspend=y
)をロードする前に、このVMを一時停止します。 デバッガ・アプリケーションが接続されたあと、そのアプリケーションがJDWPコマンドを送信してVMを再開する。 -
-agentlib:jdwp=transport=dt_socket,server=y,address=*:8000,allow=192.168.1.0/24+::1,timeout=5000
-
すべてのネットワーク・インタフェースでポート8000のソケット接続をリスニングします。 192.168.1.00アドレスからのみデバッガの接続を許可 - IPv6アドレス(::1)による192.168.1.255およびローカル・マシンから。 デバッガが5秒以内に接続しない場合は終了する。 メイン・クラスが(デフォルトでは
suspend=y
)をロードする前に、このVMを一時停止します。 デバッガ・アプリケーションが接続されたあと、そのアプリケーションがJDWPコマンドを送信してVMを再開する。 -
-agentlib:jdwp=transport=dt_shmem,server=y,suspend=n
- 使用可能な共用メモリー・トランスポートのアドレスを選択して、標準出力に出力する。 そのアドレスで共用メモリー接続を待機する。 デバッガ・アプリケーションが接続される前に、VMは実行を開始する。
-
-agentlib:jdwp=transport=dt_socket,address=myhost:8000
- ポート8000でホストmyhostのソケットを介して、実行中のデバッガ・アプリケーションにアタッチしてください。 メイン・クラスがロードされる前に、このVMを中断する。
-
-agentlib:jdwp=transport=dt_shmem,address=mysharedmemory
-
トランスポート・アドレス
mysharedmemory
で共有メモリー経由で実行中のデバッガ・アプリケーションにアタッチします。 メイン・クラスがロードされる前に、このVMを中断する。 -
-agentlib:jdwp=transport=dt_socket,server=y,address=192.168.1.18:8000,allow=*,onthrow=java.io.IOException,launch=/usr/local/bin/debugstub
-
このVMで
java.io.IOException
のインスタンスがスローされるまで待機します。 VM (デフォルトではsuspend=y
)を中断します。 ポート8000で、アドレス192.168.1.18でソケット接続をリスニングします。 デバッガが任意のアドレスから接続できるようにします。 次を実行 : "/usr/local/bin/debugstub dt_socket myhost:8000".
このプログラムは、このVMに接続してデバッグを開始する別のウィンドウでデバッガ・プロセスを起動できます。 -
-agentlib:jdwp=transport=dt_shmem,server=y,onuncaught=y,launch=d:\bin\debugstub.exe
-
uncaught例外がこのVMでスローされるのを待機する。 VMを中断する。 共用メモリー・トランスポートのアドレスを選択し、そのアドレスで接続を待機する。 次を実行 :
d:\bin\debugstub.exe dt_shmem <address>"
。<address>
は選択した共有メモリー・アドレスです。 このプログラムによって、別のウィンドウでデバッガ・プロセスが起動されてこのVMに接続され、デバッグが開始される。 -
JDBとの接続
JPDAで提供されるJavaデバッガ(JDB)の実装例は、JDIコネクタの使用方法を示しています。 JDBには、「ショートカット」オプションがあります。このオプションでは、JDBに認識されているコネクタ(リファレンス実装に存在するコネクタ)が使用されることが前提です。 また、任意のコネクタを使用して一般的な接続を確立することもできます。 JDBは最良のデバッガ・インタフェースの例ではありませんが、コネクタの簡単な使用例として参照できます。
JDBでは、-attach
オプションにより、リファレンス実装(Windows上の共有メモリー、LinuxおよびmacOS上のソケット)のいずれかのアタッチ・コネクタにアクセスできます。 -listen
オプションを使用すると、リファレンス実装(Windows上の共有メモリー、LinuxおよびmacOS上のソケット)のいずれかのリスニング・コネクタにアクセスできます。 コマンド行にクラス名と引数を直接指定すると、コマンド行起動コネクタにアクセスできます。
たとえば:
jdb -attach myhost:8000
は、ソケット・アタッチ・コネクタ (macOS上のLinux)を使用してターゲットVMに簡単にアタッチする方法です
jdb Hello 1 2 3
コマンドライン起動コネクタを使用してターゲットVMを起動する簡単な方法です。
ただし、-connect
オプションは、コネクタ名と任意の名前と値の引数ペアのセットを取得して、任意のコネクタを処理するためにJDBによって提供されます。 たとえば、前のコマンド行行の意味は次のとおりです:
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転送インタフェース」と呼ばれるトランスポート・ライブラリ・インタフェースも含まれています。 トランスポート・ライブラリは、ターゲットVMのJDWPエージェントによってロードされ、デバッガとの接続の確立、およびデバッガとVM間のJDWPパケットのトランスポートに使用されます。
詳細については、「Javaプラットフォーム・デバッガ・アーキテクチャ - サービス・プロバイダ・インタフェース」を参照してください。