-远程调试 Java 应用程序

 

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

 

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

JPDA 

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

 

JVM Tool Interface (JVMTI) 规定必须由VM提供,JavaDebug Wire Protocol (JDWP) 描述调试信息的格式,以及在被调试的进程和调试器前端之间传输的请求,调试器由前端实现 JDI,比如EclipseBorland 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项目,打包成test.jar

public class JPDATest {

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

  1. 启动参数:-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005

  2. 启动应用:

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

            (注意:这样启动程序会正常运行,如果需要程序在启动后必须等调试器连接上后才执行,那么需要设置suspend=y)

  1. 配置调试器,然后启动

远程调试tomcat

Tomcat 7默认远程调试的端口是8000Tomcat 7已经把jpda配置的属性在catalina.sh/catalina.bat里面已经写好了

方式1

1windows系统

启动

catalina.bat jpda start

修改端口号,文件catalina.bat首行加入以下代码

set JPDA_ADDRESS=58000

2linux系统

启动

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

1windows系统

文件catalina.bat首行加入以下代码

set "JAVA_OPTS=%JAVA_OPTS% -Xdebug -Xrunjdwp:transport=dt_socket,address=58000,server=y,suspend=n"

启动

startup.bat

2linux系统

文件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