杰瑞科技汇

eclipse 远程调试java

远程调试的核心原理

想象一下,远程调试就像是在你的本地 Eclipse(调试器客户端)和远程服务器上的 Java 进程(调试器目标)之间建立了一座“桥梁”。

eclipse 远程调试java-图1
(图片来源网络,侵删)
  1. 调试器客户端:你的 Eclipse IDE。
  2. 调试器目标:在远程服务器上运行的 Java 程序,它需要以“调试模式”启动,并监听一个特定的端口。
  3. 桥梁:它们之间通过 TCP/IP 网络连接进行通信,Eclipse 会发送调试命令(如设置断点、查看变量等),远程的 Java 进程会执行这些命令,并将执行结果返回给 Eclipse。

关键角色

  • jdwp (Java Debug Wire Protocol):这是 Java 调试的底层通信协议,用于在调试器和被调试的 JVM 之间传输信息。

远程调试的完整步骤

整个过程分为两大步:

  1. 在远程服务器上启动 Java 应用(调试模式)
  2. 在本地 Eclipse IDE 中配置并启动调试会话

第 1 步:在远程服务器上启动 Java 应用(调试模式)

这是最关键的一步,你需要修改启动 Java 应用的命令,添加一些 JVM 参数来启用调试功能。

核心 JVM 参数:

eclipse 远程调试java-图2
(图片来源网络,侵删)
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=<端口号>

参数详解:

  • -agentlib:jdwp:指定要加载的 JDWP (Java Debug Wire Protocol) 库。
  • transport=dt_socket:指定通信方式为套接字,这是最常用、最稳定的方式。
  • server=y:表示这个 Java 进程将作为调试服务器,等待 Eclipse 连接过来,如果设置为 n,则表示作为客户端,去连接一个正在等待的 Eclipse。
  • suspend=y非常重要! 设置为 y 时,JVM 启动后会立即暂停,等待调试器连接上之后,才开始执行你的代码,这对于在应用启动的第一行代码(如 main 方法或 Spring Boot 的 run 方法)设置断点非常有用,设置为 n 时,JVM 会立即启动并运行,直到断点被触发。
  • address=<端口号>:指定 JVM 监听的端口号,请确保这个端口在服务器上是空闲的,并且防火墙规则允许来自你本地 IP 的访问,建议使用 50058000 等常用端口。

场景示例

场景 A:调试一个普通的 Java JAR 包

假设你的 JAR 包是 my-app.jar

启动命令:

eclipse 远程调试java-图3
(图片来源网络,侵删)
# suspend=y,启动后暂停,等待连接
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005 -jar my-app.jar
# 或者 suspend=n,立即启动,运行到断点处暂停
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar my-app.jar

场景 B:调试一个 Tomcat 服务器

假设你的 Tomcat 安装在 /opt/tomcat

  1. 找到 Tomcat 的启动脚本 catalina.sh (Linux) 或 catalina.bat (Windows)。
  2. JAVA_OPTS 环境变量中添加调试参数。

修改 catalina.sh (在文件开头添加):

export CATALINA_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"

然后启动 Tomcat:

./bin/startup.sh

场景 C:调试一个 Spring Boot JAR 包

假设你的 JAR 包是 my-spring-boot-app.jar

启动命令:

# 同样,通过 javaagent 参数来设置
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar my-spring-boot-app.jar

第 2 步:在本地 Eclipse IDE 中配置并启动调试会话

  1. 打开 Java 透视图: 确保你打开的是 Java 开发透视图 (Window -> Open Perspective -> Java)。

  2. 创建调试配置

    • 点击菜单栏的 Run -> Debug Configurations...
    • 在弹出的对话框左侧,选择 Remote Java Application,然后点击右上角的 New launch configuration 图标(一个带 * 号的地球)。
  3. 配置调试信息

    • Name: 给这个配置起一个容易识别的名字,Debug Remote Tomcat
    • Project: 选择你的 Java 项目,这很重要,因为 Eclipse 需要知道源代码的位置,才能正确显示变量值和跳转到源码。
    • Connection Type: 通常保持默认的 Standard (Socket Attach)
    • Host: 输入远程服务器的 IP 地址或主机名。
    • Port: 输入你在服务器上启动应用时指定的端口号(5005)。
    • Source: 确保这里指向的是你本地项目的源代码路径。Project 选择正确后,这里会自动填充,如果项目结构复杂,可能需要手动添加 Source lookup path
  4. 设置断点: 在你本地项目的 Java 代码中,找到你想要调试的地方,双击行号左侧的空白区域,设置一个断点,断点会显示为一个蓝色的圆点。

  5. 启动调试

    • 点击 Debug 按钮(那个带虫子的图标)。
    • Eclipse 会尝试连接到远程服务器上指定的端口。

连接成功后的操作

  • 如果一切顺利,Eclipse 会切换到 Debug 透视图。
  • 你会看到:
    • Debug 视图:显示线程的调用栈。
    • Variables 视图:显示当前作用域内所有变量的值。
    • 断点会被命中:远程服务器的执行会在你设置的断点处暂停。
  • 你可以像调试本地代码一样,使用 F5 (Step Into), F6 (Step Over), F7 (Step Return), F8 (Resume) 等快捷键来控制程序的执行流程。

常见问题与解决方案

连接被拒绝 (Connection refused)

这是最常见的问题,原因通常是:

  • JVM 未启动调试模式:检查远程服务器的启动命令,确保包含了 -agentlib:jdwp=... 参数。
  • 端口不正确或未开放
    • 检查 address 端口号是否与 Eclipse 配置中的 Port 一致。
    • 在服务器上使用 netstat -tuln | grep <端口号> (Linux) 或 netstat -ano | findstr <端口号> (Windows) 检查端口是否正在监听。
    • 检查防火墙:这是最容易被忽略的一点,你需要在远程服务器的防火墙(如 iptables, firewalld, 云服务商的安全组)上开放你指定的调试端口,并允许来自你本地 IP 的访问。
    • Linux (firewalld 示例):
      sudo firewall-cmd --permanent --add-port=5005/tcp
      sudo firewall-cmd --reload
    • 云服务器 (如 AWS, 阿里云):在安全组/防火墙规则中,添加一条入站规则,协议为 TCP,端口为 5005,源 IP 为你本地的公网 IP。

源代码未找到 (Source not found)

  • 现象:在调试时,Eclipse 显示 Class File EditorSource not found,无法跳转到源码。
  • 原因:Eclipse 找不到与远程服务器上运行的 .class 文件相对应的本地 .java 源文件。
  • 解决方案
    1. 确保 Project 正确:在 Debug 配置中,Project 选项必须指向包含正确源代码的本地项目。
    2. 版本不匹配:确保你本地的源代码版本与远程服务器上编译的 .class 文件版本完全一致,即使是微小的差异也可能导致此问题。
    3. 手动关联源码
      • 在调试视图中,右键点击显示 Class File Editor 的类。
      • 选择 Edit Source Attachment...
      • 在弹出的对话框中,指向你本地项目对应的正确源代码路径或 JAR/WAR 文件。

调试连接不稳定或断开

  • 原因:网络不稳定,或者远程服务器上的应用因为其他原因(如 Full GC)导致线程暂停。
  • 解决方案
    • 尽量使用稳定的网络连接。
    • 检查服务器日志,看是否有频繁的 Full GC 等问题。

如何调试 Spring Boot 应用的启动过程?

如果你想在 Spring Boot 应用的 main 方法第一行就断下来,需要将服务器启动命令中的 suspend 参数设置为 y

# 服务器端启动命令
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005 -jar my-spring-boot-app.jar

这样,当你启动 Debug 配置并连接成功后,JVM 才会继续执行,main 方法的断点才会被命中。


Eclipse 远程调试的核心就是 “在远程以调试模式启动应用,在本地配置连接”

流程回顾

  1. 服务器端:用带 -agentlib:jdwp=... 参数的命令启动 Java 应用。
  2. 本地端
    • 在代码中设置断点。
    • 创建 Remote Java Application 调试配置,填入服务器 IP 和调试端口。
    • 点击 Debug 连接。
  3. 享受调试:连接成功后,像调试本地代码一样进行调试。

希望这份详细的指南能帮助你顺利完成远程调试!

分享:
扫描分享到社交APP
上一篇
下一篇