先决条件
如果您还没安装该程序,请下载 Eclipse V3.4(Ganymede)。在 Ganymede 中,套接字(socket)监听连接器被添加到 Remote Java Application 启动配置类型。Eclipse 最新的套接字监听连接器允许您打开 Java 调试器,它能够监听特定套接字上的连接。可以从命令行选项打开被调试的程序,并将其连接到调试器。在 Ganymede 发布之前,仅有一个连接套接字的连接器,被调试的程序所在的机器必须是一个与调试器相连的调试主机。由于受到内存和 CPU 不足的限制,要想让移动设备充当主机是不现实的。
为了进行远程调试,必须使用 Java Virtual Machine (JVM) V5.0 或更新版本,比如 IBM® J9 或 Sun Microsystem 的 Java SE Development Kit(JDK)。本文主要讨论远程调试,而不是每个 Eclipse 调试特性的细节。查看参考资料 获得更多关于使用 Eclipse 进行调试的信息,并且可以找到上面提到的软件。
JPDA 简介
Sun Microsystem 的 Java Platform Debugger Architecture (JPDA) 技术是一个多层架构,使您能够在各种环境中轻松调试 Java 应用程序。JPDA 由两个接口(分别是 JVM Tool Interface 和 JDI)、一个协议(Java Debug Wire Protocol)和两个用于合并它们的软件组件(后端和前端)组成。它的设计目的是让调试人员在任何环境中都可以进行调试。JPDA 不仅能够用于桌面系统,而且能够在嵌入式系统上很好地工作。
JVM Tool Interface (JVMTI) 规定必须为调试提供 VM(编辑注:从 Java V5 开始,将用 JVMTI 代替 Java V1.4 中的 JVMDI)。Java Debug Wire Protocol (JDWP) 描述调试信息的格式,以及在被调试的进程和调试器前端之间传输的请求,调试器前端实现 JDI,比如 Eclipse、Borland JBuilder 等。根据 Sun 的 JPDA 规范,被调试的程序常常称为debuggee。JDI 是一个高级的接口,它定义用于远程调试的信息和请求。下面给出了调试器的架构。
Components Debugger Interfaces / |--------------| / | VM | debuggee -----( |--------------| <---- JVMTI - Java VM Tool Interface \ | back-end | \ |--------------| / | comm channel --( | <------------ JDWP - Java Debug Wire Protocol \ | / |--------------| / | front-end | debugger -----( |--------------| <---- JDI - Java Debug Interface \ | UI | \ |--------------| |
因此,任何第三方工具和基于 JPDA 的 VM 应该都能协调工作。通过这个客户机-服务器架构,您可以从运行该平台的本地工作站调试 Java 程序,甚至还可以通过网络进行远程调试。
在讨论调试场景之前,我们先了解 JPDA 规范中的两个术语:连接器和传输。连接器是一个 JDI 抽象,用来在调试器应用程序和目标 VM 之间建立连接。传输定义应用程序如何进行访问,以及数据如何在前端和后端之间传输。连接器 “映射” 到可用的传输类型和连接模式。在 Sun 的 JPDA 参考实现中,为 Microsoft® Windows® 提供了两个传输机制:套接字传输和共享内存传输。可用的连接器:
在调试器应用程序和目标 VM 之间建立连接时,有一端将用作服务器并监听连接。随后,另一端将连接到监听器并建立一个连接。通过连接,调试器应用程序或目标 VM 都可以充当服务器。进程之间的通信可以在同一个机器或不同的机器上运行。
要远程调试 Java 程序,难点不是在调试器的前端,而是远程 Java 后端。不幸的是,Eclipse 帮助系统中为这方面提供的信息并不多。事实上,JDI 和 JVMTI 是分别由 Eclipse 和 Java 运行时环境实现的。我们仅需要考虑 JDMP,因为它包含与 JVMTI 和 JDI 进行通信所需的信息。JDWP 包含许多参数,用于为远程 Java 应用程序调用所需的程序。以下是本文用到的一些参数。
从 Java V5 开始,您可以使用 -agentlib:jdwp 选项,而不是 -Xdebug 和 -Xrunjdwp。但如果连接到 V5 以前的 VM,只能选择-Xdebug 和-Xrunjdwp。下面简单描述 -Xrunjdwp 子选项。
要获得每个调试设置的详细解释,请参考 JPDA 文档(参见 参考资料)。
清单 2 是一个示例,显示如何在调试模式下启动 VM 并监听端口 8765 的套接字连接。
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8765 |
清单 3 显示如何使用位于 8000 端口的主机 127.0.0.1 上的套接字连接运行中的调试器应用程序。
-Xdebug -Xrunjdwp:transport=dt_socket,address=127.0.0.1:8000 |
回页首
Eclipse 中的远程调试特性
Eclipse 是一个图形化 Java 调试器前端。JDI 在 org.eclipse.jdt.debug 包中实现。本文不详细讨论 JDI 实现。参见 参考资料 获得关于 Eclipse JDT 和 Java JDI 技术的信息。
我们首先应该知道要使用哪个 Eclipse 连接器。要了解 Eclipse 提供的远程连接类型,您可以转到 Eclipse 菜单并选择 Run > Debug Configurations...,在Remote Java Application
中添加一个启动配置,然后从下拉列表中选择连接器。在 Ganymede 中共有两个连接器:
对于监听套接字的连接器,Eclipse VM 将是与远程 Java 应用程序连接的主机。对于连接套接字的连接器,目标 VM 将作为主机。这两种连接器对应用程序调试没有影响,用户可以任意选择。但根据经验,需要使用速度更快、更强大的计算机作为 VM 调试主机,因为需要计算的资源很多。
在调试 Java 应用程序之前,需要确保已经为远程应用程序启用所有调试选项。如果选项信息不可用,您将收到一个错误信息,比如 “Debug information is not available” 或 “Unable to install breakpoint due to missing line number”。您可以通过更改 Eclipse 菜单上的Window > Preferences > Java > Compiler 来修改设置。
回页首
远程调试应用程序
现在,我们已经准备好远程调试应用程序。我们分步执行:
package com.ibm.developerWorks.debugtest; public class test { public static void main(String[] args) { System.out.println("This is a test."); } } |
System.out.println("This is a test.");
这行中设置断点。
java -jar test.jar |
作为调试服务器的目标 VM
下面这个示例远程调用 Java 应用程序作为调试服务器,并在端口 8000 监听套接字连接。目标 VM 将暂停,直到调试器连接。
java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address="8000" -jar test.jar |
使用远程启动配置启动 Eclipse,并指定远程应用程序的目标 VM 地址。为此,单击 Run > Debug Configurations,然后在 Eclipse 菜单中双击Remote Java Application。从最新创建的启动配置中为目标应用程序指定 IP 和端口。为了在同一台机器上运行远程应用程序,仅需将主机 IP 指定为 localhost 或 127.0.0.1。
选择 Allow termination of remote VM 选项终止在应用程序调试期间连接的 VM。
作为调试客户机的目标 VM
第二个示例使用一个简单的 Java 应用程序作为调试客户机,并且调试器前端作为调试服务器。Eclipse 使用套接字监听模式连接类型进行监听。必须先启动调试前端来监听特定的端口。图 6 给出一个用于设置监听的示例配置。
单击 Eclipse Debug 按钮,状态栏将显示消息 “waiting for vm to connect at port 8000...”。看到这个消息后,启动远程应用程序。清单 7 显示了如何将 Java 应用程序作为调试客户机并调用它,然后使用端口 8000 上的主机 127.0.0.1 的套接字将其连接到一个正在运行的调试器应用程序。
java -Xdebug -Xrunjdwp:transport=dt_socket,address=127.0.0.1:8000,suspend=y -jar test.jar |
如果一切进行顺利,将会显示一个调试透视图帮助调试应用程序,并且远程 Java 应用程序将正常停止。这类似于步骤 3 中的本地调试(参见图 3)。在这里,您可以使用标准的调试特性,比如设置断点和值、单步执行等。
何为远程调试?
我们一般调试一个 web项目的java代码时,需要将你的tomcat服务器和你的开发工具(比如Jbuilder)集成,或需要工具的一些插件支持(比如Eclipse 下的myclipse等),这些方式都是在本地进行,即你的开发工具和tomcat运行在同一台服务器上,如果你的开发工具和服务器不再一台机器上那就需要实现远程调试功能了。
实现方法:
在tomcat的catalina.bat文件中加入下面的设置,当然SET CATALINA_OPTS 变量应该在使用它之前。这是在tomcat启动时设置一些虚拟机参数,使服务器允许远程连接功能,address=5888表示远程连接的端口号,可以设 置成任意其他不冲突端口。其他的应用服务器比如weblogic也应该可以设置这些参数,有兴趣的可以测试。
SET CATALINA_OPTS=-server -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5888
这 样就Ok了,重启动tomcat,可以直接独立启动,而不用在eclipes的插件中启动。打开eclipse中的debug设置窗口,选择Remote Java Application ,新建一个debug项,输入服务器IP和刚才设置端口号,点ok就可以进入debug状态了。Jbuilder中同样可以设置Remote Java Application。
回页首
结束语
本文演示如何使用 Eclipse 内置的远程 Java 应用程序配置类型对应用程序执行远程调试。介绍了如何设置 Java 应用程序以调用远程调试,并帮助您理解 Eclipse 提供的连接器。最后,您还学习了如何将这些技术应用到项目中。
参考资料
学习
获得产品和技术
讨论
关于作者
Charles Lu 是 IBM China Software Development Lab 的软件开发人员,目前从事 IBM Lotus Expeditor 的开发。他感兴趣的领域包括设备编程、即时消息和语音技术。