-远程调试 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 将暂停,直到调试器应用程序进行连接。
远程调试应用程序
使用简单类创建一个java项目,打包成test.jar。
public class JPDATest { public static void main(String[]args) { System.out.println("Thisis a test."); }}
启动参数:-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
启动应用:
java –jar -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005test.jar
(注意:这样启动程序会正常运行,如果需要程序在启动后必须等调试器连接上后才执行,那么需要设置suspend=y)
配置调试器,然后启动
远程调试tomcat
Tomcat 7默认远程调试的端口是8000,Tomcat 7已经把jpda配置的属性在catalina.sh/catalina.bat里面已经写好了。
方式1
1、windows系统
启动
catalina.bat jpda start
修改端口号,文件catalina.bat首行加入以下代码
set JPDA_ADDRESS=58000
2、linux系统
启动
catalina.sh jpda start
修改端口号,文件catalina.sh首行加入以下代码
JPDA_ADDRESS="58000"
开放端口号,修改/etc/sysconfig/iptables增加一行代码,然后再重启iptables服务/etc/init.d/iptablesrestart
-A INPUT -m state --state NEW -m tcp -p tcp --dport 58000 -j ACCEPT
方式2
1、windows系统
文件catalina.bat首行加入以下代码
set "JAVA_OPTS=%JAVA_OPTS% -Xdebug -Xrunjdwp:transport=dt_socket,address=58000,server=y,suspend=n"
启动
startup.bat
2、linux系统
文件catalina.sh首行加入以下代码
JAVA_OPTS="${JAVA_OPTS} -Xdebug -Xrunjdwp:transport=dt_socket,address=58000,server=y,suspend=n"
启动
./startup.sh
开放端口号,修改/etc/sysconfig/iptables增加一行代码,然后再重启iptables服务/etc/init.d/iptablesrestart
-A INPUT -m state --state NEW -m tcp -p tcp --dport 58000 -j ACCEPT