JDWPを有効にしてリモートマシンで動いているJavaアプリケーションをデバッグする

javaintellij

JDWPを有効にする

実行時に -agentlib:jdwp を渡すとJVMとデバッガーがやり取りする際に用いられるJDWP(Java Debug Wire Protocol)を有効にできる。

  • transport=dt_socket,server=y,address=*:5005 5005番ポートでデバッガーを待ち受ける。Java 8以前は *: が不要。
  • suspend=n メインクラスがロードされる直前にJVMを一時停止しない

処理が終わると終了するタイプのアプリケーションでは、先にデバッガーを起動し待ち受けておいて、server=n で接続しにいったり、 suspend=y にしてデバッガーが接続されるまで停止させることができる。

$ java --version
openjdk 18.0.1 2022-04-19
OpenJDK Runtime Environment Corretto-18.0.1.10.1 (build 18.0.1+10-FR)
OpenJDK 64-Bit Server VM Corretto-18.0.1.10.1 (build 18.0.1+10-FR, mixed mode, sharing)

$ java -jar -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 out/artifacts/debugtest_jar/debugtest.jar 
Listening for transport dt_socket at address: 5005
Start server on :8080

ポートフォワーディング

SSHやAWS SSMなどでポートフォワーディングしてデバッガーがリモートマシンのJVMに接続できるようにする。

$ ssh [email protected] -Nf -L 5005:localhost:5005 
$ aws ssm start-session --target instance_name --document-name AWS-StartPortForwardingSession --parameters '{"portNumber":["5005"], "localPortNumber":["5005"]}'

SSHポートフォワーディングする際のオプション - sambaiz-net

AWS CopilotでECS on Fargate上にコンテナをデプロイしECS Execによるコマンドの実行やSession Managerによるポートフォワーディングを行う - sambaiz-net

実行

IntelliJの場合、Run > Edit Configurations から Remote JVM Debug を追加できる。

Connected to the target VM, address: 'localhost:5005', transport: 'socket'