我们在使用Java语言进行开发时,会经常需要调试代码。对于小规模的项目,可以采用在开发所使用的IDE中给程序加断点,然后单步执行的方式来执行。但对于大规模的项目,我们不可能将全部代码加载到开发环境中单步执行,这时就需要使用JDK提供的JDWP远程调试协议进行代码调试。本文讲解如何使用Eclipse结合JDWP进行项目调试。
假设我们想要调试Maven,由于Maven是非常大的一个项目,我们会需要先将它执行起来,然后把调试器连接至程序的执行虚拟机中,在调试器中导入相关程序,并加入断点。而JDWP使这一工作成为可能。JDWP的全称是Java Debug Wire Protocol,它定义了调试器(debugger)和被调试的 Java 虚拟机(target vm)之间的通信协议。有关JDWP的具体原理介绍,不是本文的重点,有兴趣请参考附录[1]。
本文的重点是如何使用JDWP和Eclipse进行远程调试。比如我们需要调试Maven,而Maven做为一个项目管理的基础工具,将其导入到IDE中逐行调试不太现实,我们于是可以在Maven命令执行前加入一行参数:
export MAVEN_OPTS=-Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y
如果是在Windows环境下,则是:
set MAVEN_OPTS=-Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y
此时在某个由Maven管理的工程下执行mvn指令,将会使mvn进入远程调试状态,开通我们配置的侦听端口号8787:
% mvn install
listening for transport dt_socket at address: 8787
此时,mvn程序便进入了等待调试的状态。此时我们便可以使用Eclipse对mvn进行调试。首先我们知道mvn的入口程序是MavenCLI.java,因此将这个代码导入Eclipse便可以开始调试:
如上图所示,与常规的调试不同,我们选择Debug Configuration,进入配置页面:
按照上图,选择Remote Java Application,配置好要调试的项目,端口号写为8787,点选Debug按钮,然后将Eclipse选择为Debug模式,如果在MavenCli.java里面已经配置好了断点,便可以开始调试了:
如果我们需要调试MavenCli以外的代码,将相应的执行到的程序导入Eclipse便可以了,Eclipse会自动根据代码的执行情况转入相应的代码。这样,像JBoss或Tomcat这样比较大型的项目也可以很方便地进行跟踪调试。
参考资料
深入 Java 调试体系,第 3 部分: JDWP 协议及实现