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.batset JPDA_ADDRESS=8000
linux修改catalina.shJPDA_ADDRESS="8000"
2、如果习惯使用startup.sh启动
windows修改startup.batcall "%EXECUTABLE%" start %CMD_LINE_ARGS%
修改为
call "%EXECUTABLE%" jpda start %CMD_LINE_ARGS%
linux修改startup.shexec "$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"