无法在 docker 容器中远程调试 Java 9 Tomcat 9

Posted

技术标签:

【中文标题】无法在 docker 容器中远程调试 Java 9 Tomcat 9【英文标题】:Can't remotely debug on Java 9 Tomcat 9 in docker container 【发布时间】:2018-04-20 11:06:46 【问题描述】:

我有一个基于 opendjdk:8-slim 并安装了 Tomcat 9 的 Docker 容器,我正在调试从我的 IDE (IntelliJ) 部署的应用程序 - IDE 在 Docker 主机上运行。我使用以下配置运行 Tomcat

CATALINA_OPTS="-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=49520 \
-Dcom.sun.management.jmxremote.rmi.port=49520 \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.local.only=false \
-Djava.rmi.server.hostname=10.0.75.1 \
-agentlib:jdwp=transport=dt_socket,address=49540,suspend=n,server=y"

一切都很好 - 我可以将 IDE 附加到容器上。以下命令也有效(从 docker 主机执行) - 它可以连接到容器中的进程(容器中的端口 49540 映射到主机上的端口 49540):

docker-host$ telnet localhost 49540

现在我想升级到 Java 9。我将基础映像从 openjdk:8-slim 更改为 openjdk:9-slim,但我无法从 docker 主机连接到调试器端口。同样来自 IDE,我得到了SocketTimeoutException: Connection reset。但是,在容器内部,我可以通过telnet 连接到调试器。

我从openjdk 存储库和其他存储库(例如adenix/java)尝试了几张Java 9 图像,但不幸的是得到了相同的结果。

【问题讨论】:

试试address=0.0.0.0:49540看看有没有帮助 在JDK 9中,JDWP默认绑定到localhost,yu可能需要指定address=*。此处发布说明中的更多详细信息:oracle.com/technetwork/java/javase/… @AlanBateman 非常感谢您提供的线索!我试图指定地址 - * 和具体的 IP 地址 192.168.16.1。现在我在Tomcat启动过程中遇到以下错误:ERROR: transport error 202: bind failed: Cannot assign requested address ERROR: JDWP Transport dt_socket failed to initialize, TRANSPORT_INIT(510) JDWP exit error AGENT_ERROR_TRANSPORT_INIT(197): No transports initialized [debugInit.c:730]我试图从容器中ping IP地址并且它成功了。 "Cannot assign ..." 表明这不是 docker 容器中的地址。我很惊讶 address=*:49540 不起作用,因为它相当于 JDK 8 中的 address=49540 【参考方案1】:

最后我找到了一种方法,如何使用 Alan Bateman 提供的评论中的信息使其工作。

我没有在CATALINA_OPTS 中设置调试设置(与JDK 8 一起使用没有问题),而是设置JPDA_OPTS="-agentlib:jdwp=transport=dt_socket,address=*:4954‌​0,server=y,suspend=n‌​" 并使用catalina.sh jpda run 运行Tomcat。具体的 IP 地址(例如 address=192.168.16.1:49540)仍然对我不起作用,尽管可以从容器内访问 IP 地址。

【讨论】:

谢谢。在 tomcat-9、JDK-11 上为我工作 要点是,在 Java 8 及更早版本中,当您将端口指定为 address 时,它会侦听所有 IP 地址,例如address=4954‌​0。从 Java 9 开始,默认情况下它只会监听 127.0.0.1,并且您需要明确指定要监听所有 IP 地址,例如address=*:4954‌​0.【参考方案2】:

我在我的 docker-compose.yaml 中使用这个环境变量在 Java 9Tomcat 9 中运行:

...
    environment:
      - "JPDA_ADDRESS=*:8000"
...

Java 8 之前我使用的是:

...
    environment:
      - "JPDA_ADDRESS=8000"
...

【讨论】:

这也是我的问题。现在它正在工作。

以上是关于无法在 docker 容器中远程调试 Java 9 Tomcat 9的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 VS Code 在 Docker 容器中远程调试 python 代码

Docker容器中的Intellij CE 2018.2 + SBT:远程调试断点无法正常工作

从 Docker 容器内部使用 XDebug 进行远程调试不起作用

远程服务器上 Docker 内的 Xdebug 远程调试

在远程服务器上的Docker内部进行Xdebug远程调试

在 Windows 容器中运行 Visual Studio 远程调试器(由 Docker 管理)