Java 9 以降でリモートデバッグするときはホストの指定も必要


環境

OS

Windows 10 64bit

Java

> java --version
openjdk 11.0.3 2019-04-16
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.3+7)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.3+7, mixed mode)

検証用の実装

フォルダ構成
> tree /f
├─build
│  └─classes
│     └─java
│         └─main
│                 Hoge.class
└─src
    └─main
        └─java
                Hoge.java
Hoge.java
class Hoge {
    public static void main(String... args) {
        System.out.println("Hello World");
    }
}

Java 9 より前

Java のプログラムを Eclipse とかでデバッグするときは、起動時のオプションに次のような呪文を追加する。


> java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8000,suspend=y -cp build\classes\java\main Hoge

Java 9 より前であれば、これでリモートから 8000 ポート指定でデバッガーをつなぐことができた(もちろんポートを開いておく必要はある)。

Java 9 以降だとエラーになる

しかし、 Java 9 以降でこのオプションで起動した JVM にリモートからデバッガで繋ごうとすると、次のようなエラーになる。

Java 9 で、ホスト指定していない場合はリモートから接続できなくなった

JDK 9 Release Notes | Notes and Changes

JDWP socket connector accept only local connections by default
The JDWP socket connector has been changed to bind to localhost only if no ip address or hostname is specified on the agent command line. A hostname of asterisk (*) may be used to achieve the old behavior which is to bind the JDWP socket connector to all available interfaces; this is not secure and not recommended.

Java 9 で、ホストを指定していない場合は自動的に localhost にバインドされるようになり、リモートからは接続できなくなったらしい。

これまで通り任意のリモートから接続できるようにするには、 address=*:8000 のように * を使うことで実現できる。
(ただし、セキュリティ的によくないので推奨はされないらしい1

* 指定で接続してみる

> java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=*:8000,suspend=y -cp build\classes\java\main Hoge

つながった。

参考


  1. デバッガで接続する時点で本番ではない環境だし別にそこまで気にする必要はない気はする。え?本番もデバッガで接続する?アッハイ