目录
-
- 背景
- 总结
- [根因:JDK 9+ 改了 JDWP 的默认绑定地址](#根因:JDK 9+ 改了 JDWP 的默认绑定地址)
-
- [JDK 8 vs JDK 9+](#JDK 8 vs JDK 9+)
- [为何 JDK 要改?](#为何 JDK 要改?)
- 如何快速确认
-
- [1. 开发机(Mac)](#1. 开发机(Mac))
- [2. 远程服务器](#2. 远程服务器)
- [3. 对照表](#3. 对照表)
- 解决方案
-
- [方案 A:SSH 端口转发(推荐,安全)](#方案 A:SSH 端口转发(推荐,安全))
- [方案 B:改远程 JDWP,允许对外监听](#方案 B:改远程 JDWP,允许对外监听)
- [与 VS Code / launch.json 的关系](#与 VS Code / launch.json 的关系)
- [团队 checklist(JDK 17 远程调试)](#团队 checklist(JDK 17 远程调试))
背景
团队在 Mac 上用 VS Code 远程调试部署在 myhost 上的 Tomcat(clouddatahub)。launch.json 使用 Java attach 模式:
json
{
"type": "java",
"request": "attach",
"hostName": "myhost",
"port": 5005
}
JDK 8 时代一直正常;迁移到 JDK 17 后出现:
text
java.io.IOException: Failed to attach to myhost:5005
(attach timeout 30000, handshake timeout 0)
总结
JDK 8 上 address=5005 往往能被远程 attach;JDK 9+ 同写法默认只监听本机。升级到 JDK 17 后远程调试超时,多半是监听地址策略变了,而不是 IDE 配错。用 SSH 隧道或 address=*:5005 即可恢复,并注意生产环境安全。*
根因:JDK 9+ 改了 JDWP 的默认绑定地址
远程 JVM 常通过 CATALINA_OPTS / JAVA_OPTS 开启调试,例如:
text
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
JDK 8 vs JDK 9+
| 配置 | JDK 8(及更早) | JDK 9+(含 11、17) |
|---|---|---|
address=5005 |
多在 5005 端口监听,常可从其他机器 attach | 默认只绑定 127.0.0.1,仅本机可连 |
| 远程 IDE attach 同一 hostname:5005 | 通常可以 | 会超时(除非做 SSH 隧道或改配置) |
| 要对局域网/远程开放 | 历史上"只写端口"往往就够 | 必须显式 写,例如 address=*:5005 |
升级 JDK 后若未改 JDWP 参数,会出现:
- 在服务器本机
nc localhost 5005→ 可能通 - 在开发机
nc myhost 5005→ 超时
这与 VS Code、launch.json 无关,是 JVM 监听范围变了。
为何 JDK 要改?
- 远程调试等于给 JVM 开高权限调试入口;仅写端口容易在不知情下对全网开放 5005。
- JDK 9 起:只写端口 = 仅本机调试 ;要远程调试需 opt-in (
*等)。 - 属于 intentional 安全策略,不是 Tomcat 或 IDE 的 bug。
如何快速确认
1. 开发机(Mac)
bash
nc -zv myhost 5005
- 超时 → 防火墙、未映射端口,或 JVM 只监听 127.0.0.1
- Connection refused → 未开 JDWP、端口错误或 Tomcat 未起
2. 远程服务器
bash
ss -tlnp | grep 5005
ps aux | grep jdwp
关注监听地址:
text
127.0.0.1:5005 # 仅本机 → 跨机 attach 会失败(JDK 9+ 下 address=5005 常见)
0.0.0.0:5005 # 或 *:5005 → 可从其他机器连(需防火墙放行)
3. 对照表
本机 nc |
远程 ss |
结论 |
|---|---|---|
| 超时 | 无 5005 | 未开 JDWP 或 Tomcat 未启动 |
| 超时 | 127.0.0.1:5005 |
典型:JDK 9+ 只监听本机 |
| 超时 | 0.0.0.0:5005 |
查防火墙 / 安全组 |
| 成功 | java 在听 | attach 应可成功 |
解决方案
方案 A:SSH 端口转发(推荐,安全)
不改远程 JVM,继续 address=5005(只监听本机):
bash
ssh -L 5005:127.0.0.1:5005 user@myhost
launch.json 改为:
json
"hostName": "localhost",
"port": 5005
流量经 SSH 加密,5005 不暴露到公网,适合 draft/内网环境。
方案 B:改远程 JDWP,允许对外监听
在 Tomcat 启动参数中(JDK 9+)使用:
text
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
launch.json 可继续 hostName: myhost。
注意:
- 必须在防火墙 / 安全组中按需放行 5005,且限制来源 IP。
- 生产环境慎用;draft 也建议仅内网 + IP 白名单。
- 改完后需重启 Tomcat,并再次
ss -tlnp | grep 5005验证。
与 VS Code / launch.json 的关系
attach 配置里的 projectName、sourcePaths 只影响断点命中后的源码映射 ,不会导致 attach timeout。
排查顺序建议:
- 本机能否连上 5005(
nc) - 远程 JDWP 绑定地址(
ss+ 启动参数) - 是否需要 SSH 隧道或
address=*:5005 - 再查源码版本是否与远程 WAR 一致
团队 checklist(JDK 17 远程调试)
- 远程
ps/ss确认 JDWP 已启用且端口正确 - 确认
address=5005在 JDK 17 下是否只监听127.0.0.1 - 跨机调试:二选一 --- SSH
-L 5005:127.0.0.1:5005+ localhost ,或address=*:5005+ 防火墙 - 本机
nc -zv <host> 5005通过后再点 VS Code Debug - 升级 JDK 时把
CATALINA_OPTS里的 JDWP 一并 review