Java 调试体系(二)-远程调试 Java 应用程序

 

    远程调试对应用程序开发十分有用。例如,为不能托管开发平台的低端机器开发程序,或在专用的机器上(比如服务不能中断的 Web 服务器)调试程序。其他情况包括:运行在内存小或 CUP 性能低的设备上的 Java 应用程序(比如移动设备),或者开发人员想要将应用程序和开发环境分开,等等。

    为了进行远程调试,必须使用 Java Virtual Machine (JVM) V5.0 或更新版本,比如IBM J9 或 Sun Microsystem 的 Java SE Development Kit(JDK)。

JPDA 

    JPDA 由两个接口(分别是 JVMTool Interface 和 JDI)、一个协议(Java Debug Wire Protocol)和两个用于合并它们的软件组件(后端和前端)组成。它的设计目的是让调试人员在任何环境中都可以进行调试。JPDA 不仅能够用于桌面系统,而且能够在嵌入式系统上很好地工作。

JVM Tool Interface (JVMTI) 规定必须由VM提供,JavaDebug Wire Protocol (JDWP) 描述调试信息的格式,以及在被调试的进程和调试器前端之间传输的请求,调试器由前端实现 JDI,比如Eclipse、Borland JBuilder 等。

  在讨论调试场景之前,我们先了解 JPDA 规范中的两个术语:连接器和传输。连接器是一个 JDI 抽象,用来在调试器应用程序和目标 VM 之间建立连接。传输定义应用程序如何进行访问,以及数据如何在前端和后端之间传输。连接器 “映射” 到可用的传输类型和连接模式。 

在调试器应用程序和目标 VM 之间建立连接时,有一端将用作服务器并监听连接。随后,另一端将连接到监听器并建立一个连接。通过连接,调试器应用程序或目标 VM 都可以充当服务器。进程之间的通信可以在同一个机器或不同的机器上运行。

  要远程调试 Java 程序,难点不是在调试器的前端,而是远程 Java 后端。不幸

的是,Eclipse 帮助系统中为这方面提供的信息并不多。事实上,JDI 和 JVMTI 是分别由 Eclipse 和 Java 运行时环境实现的。我们仅需要考虑 JDMP,因为它包含与 JVMTI 和 JDI 进行通信所需的信息。JDWP 包含许多参数,用于为远程 Java 应用程序调用所需的程序。以下是本文用到的一些参数。

-agentlib:jdwp 

    在目标 VM 中加载 JDWP 实现。它通过传输和 JDWP 协议与独立的调试器应用程序通信。

transport

    这里通常使用套接字传输。但是在 Windows 平台上也可以使用共享内存传输。

server

    如果值为 y,目标应用程序监听将要连接的调试器应用程序。否则,它将连接到特定地址上的调试器应用程序。

address

    这是连接的传输地址。如果服务器为 n,将尝试连接到该地址上的调试器应用程序。否则,将在这个端口监听连接。

suspend

    如果值为 y,目标 VM 将暂停,直到调试器应用程序进行连接。

远程调试应用程序

1、使用简单类创建一个 Java 项目

public class Test {     public static void main(String[] args){            System.out.println("This is a test.");            }    }

2、设置启动参数:

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

3、启动java程序,可以使用java或者java -jar启动。启动时添加第二步设置的启动参数。例如:

java -jar -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 test.jar

4、配置调试器连接到jvm,我这边使用idea。Host填写远程ip,Port填写上一步的address

远程调试tomcat

tomcat已经默认配置了jpda参数,使用即可。端口默认为8000。

1、使用tomcat默认参数启动

windows启动:

catalina.bat jpda start

linux启动:

catalina.sh jpda start

如果需要修改默认端口

windows修改catalina.bat

set JPDA_ADDRESS=8000

linux修改catalina.sh

JPDA_ADDRESS="8000"

2、如果习惯使用startup.sh启动

windows修改startup.bat

call "%EXECUTABLE%" start %CMD_LINE_ARGS%修改为call "%EXECUTABLE%" jpda start %CMD_LINE_ARGS%

linux修改startup.sh

exec "$PRGDIR"/"$EXECUTABLE" start "$@"修改为exec "$PRGDIR"/"$EXECUTABLE" jpda start "$@"

3、配置自定义jpda参数

windows下在catalina.bat第一行添加

set JPDA_OPTS= -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005

linux下在catalina.sh第一行添加

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