远程调试对于应用程序开发很有用,例如为无法承载开发平台的低端计算机开发程序,或者在无法关闭服务的专用计算机(如Web服务器)上调试程序。 其他示例包括以有限的内存或CPU能力运行的Java应用程序(例如移动设备)或想要分离应用程序和开发环境的开发人员等。
先决条件
如果尚未安装,请下载Eclipse V3.4(Ganymede)。 在Ganymede中,套接字侦听连接器已添加到“远程Java应用程序”启动配置类型中。 Eclipse的新套接字侦听连接器允许您启动Java调试器,该侦听器侦听特定套接字上的连接。 然后可以使用命令行选项启动要调试的程序以连接到调试器。 在Ganymede发行版之前,仅提供了套接字连接连接器,并且要调试的程序必须是由调试器连接的调试主机。 由于内存和CPU能力不足,将移动设备作为主机是不切实际的。
要使用远程调试,必须使用Java虚拟机(JVM)V5.0或更高版本,例如IBM®J9或Sun Microsystems的Java SE开发工具包(JDK)。 在本文中,我们专注于远程调试,而不是详细介绍每个Eclipse的调试功能。
JPDA简介
Sun Microsystems的Java平台调试器体系结构(JPDA)技术是一种多层体系结构,使您可以在所有情况下轻松调试Java应用程序。 JPDA由两个接口(分别为JVM Tool Interface和JDI),一个协议(Java Debug Wire Protocol)和将它们联系在一起的两个软件组件(后端和前端)组成。 它是为调试器在任何环境中使用而设计的。 JPDA不仅适用于台式机系统,而且也适用于嵌入式系统。
JVM工具接口(JVMTI)定义了VM必须提供的调试功能。 ( 编者注:从Java V5开始,JVMTI替代了Java V1.4中使用的JVMDI。)Java调试线协议(JDWP)描述了调试信息的格式以及在被调试进程和调试器前端之间传输的请求。 ,它实现了JDI,例如Eclipse,Borland JBuilder等。 被调试的程序在Sun的JPDA规范中通常称为debuggee 。 JDI是一个高级接口,用于定义用于远程调试的信息和请求。 该架构的结构如下。
清单1. Java平台调试器体系结构
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程序,甚至从网络上的远程计算机调试Java程序。
在讨论调试场景之前,我们需要介绍JPDA规范中使用的两个术语:连接器和传输。 连接器是用于在调试器应用程序和目标VM之间建立连接的JDI抽象。 传输定义了应用程序如何在前端和后端之间访问和传输数据。 连接器“映射”到可用的传输类型和连接方式。 在Sun的JPDA参考实现中,Microsoft®Windows®上提供了两种传输机制:套接字传输和共享内存传输。 可用的连接器:
- 插座连接器
- 共享内存连接器
- 插座监听连接器
- 共享内存监听连接器
- 命令行启动连接器
在调试器应用程序和目标VM之间建立连接时,一侧充当服务器并侦听连接。 稍后,另一端连接到侦听器并建立连接。 这些连接允许调试器应用程序或目标VM充当服务器。 进程之间的通信可以在一台计算机上运行,也可以在不同的计算机上运行。
远程调试Java程序的问题不在调试器前端,而在远程Java后端。 不幸的是,Eclipse帮助系统中对此的信息并不多。 实际上,JDI和JVMTI分别由Eclipse和Java运行时环境实现。 我们唯一关心的是JDWP,它包含与JVMTI和JDI通信的信息。 JDWP包含许多已添加的参数,以调用远程Java应用程序的应用程序。 以下是本文中使用的一些参数。
-
-Xdebug
- 启用调试功能。
-
-Xrunjdwp: <子选项>
- 在目标VM中加载JDWP的实现。 它使用传输和JDWP协议与单独的调试器应用程序进行通信。 具体的子选项如下所述。
从Java V5开始,可以使用-agentlib:jdwp选项,而不是-Xdebug和-Xrunjdwp 。 但是,如果必须在V5之前连接到VM,则-Xdebug和-Xrunjdwp将是唯一的选择。 以下是-Xrunjdwp子选项的简要说明。
-
运输
- 通常,使用套接字传输。 但是,共享内存传输也可以在Windows平台上使用(如果有)。
-
服务器
- 如果值为y ,则目标应用程序侦听要附加的调试器应用程序。 否则,它将在指定地址附加到调试器应用程序。
-
地址
- 这是连接的传输地址。 如果服务器为n ,则尝试在此地址附加到调试器应用程序。 否则,请侦听此端口上的连接。
-
暂停
- 如果值为y ,则目标虚拟机将被挂起,直到连接调试器应用程序为止。
有关每种调试设置的详细说明,请参阅JPDA文档。
清单2显示了如何以调试模式启动VM并在端口8765侦听套接字连接的示例。
清单2.目标VM充当调试服务器
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8765
清单3显示了如何使用主机127.0.0.1上端口8000上的套接字将附加到正在运行的调试器应用程序。
清单3.目标VM充当调试客户端
-Xdebug -Xrunjdwp:transport=dt_socket,address=127.0.0.1:8000
Eclipse中的远程调试功能
Eclipse是图形Java调试器的前端。 JDI在org.eclipse.jdt.debug包中实现。 在本文中,我们不会讨论JDI实现的细节。
我们想知道的第一件事是使用哪个Eclipse连接器。 要了解Eclipse提供的远程连接类型,可以通过以下方法在“ Remote Java Application
添加启动配置Remote Java Application
转到Eclipse菜单,然后选择“ 运行”>“调试配置...” ,然后从下拉列表中选择连接器。 Ganymede提供了两个连接器:
- 插座连接
- 套接字监听
对于套接字侦听连接器,Eclipse VM将成为远程Java应用程序要连接的主机。 对于套接字连接器,目标VM将是主机。 两个连接器之间的应用程序调试没有区别-用户可以选择。 一个好的经验法则是,由于需要计算资源,因此使用速度更快,功能更强大的计算机作为VM调试主机。
在调试Java应用程序之前,您可能需要确保已为远程应用程序启用了所有调试选项。 如果该信息不可用,您将收到一条错误消息,例如“调试信息不可用”或“由于缺少行号而无法安装断点”。 您可以通过更改“ 窗口”>“首选项”>“ Java”>“编译器”中的设置来从Eclipse菜单中修改设置。
图1. Eclipse中的调试选项
远程调试应用程序
我们准备开始远程调试应用程序。 让我们逐步进行:
-
1.用一个简单的类创建一个Java项目
- 我们创建一个用于调试目的的简单类。 清单4显示了示例代码。
清单4.用于调试的示例代码
package com.ibm.developerWorks.debugtest;
public class test {
public static void main(String[] args) {
System.out.println("This is a test.");
}
}
-
2.设置一个断点
-
在代码中设置一个断点。
在此示例中,我们在
System.out.println("This is a test.");
行中设置断点System.out.println("This is a test.");
。
图2.在Eclipse中设置断点
-
3.在本地调试应用程序
- 在调试应用程序之前,请确保为项目启用了图1中描述的调试选项。 不必在本地调试应用程序,但是我们可以确保所有调试信息均可用。 右键单击Java项目,选择Debug As,然后选择Java Application (参见图3)。 如果应用程序的执行在断点处停止,则调试信息将正确显示。 您可以继续使用调试功能,例如显示调试堆栈,变量或断点管理等。
图3.在本地调试应用程序
-
4.导出Java项目
- 我们将使用此应用程序作为调试目标。 右键单击Java项目,选择Export ,选择Java ,然后选择JAR文件或Runnable JAR文件以导出项目。 JAR文件将在所需位置生成。 请注意,如果Java源与目标应用程序不匹配,则调试功能将无法正常工作。
-
5.手动运行Java应用程序
- 打开控制台以手动启动应用程序,以确保正确配置了Java运行时环境。
清单5.调用Java应用程序的示例
java -jar test.jar
-
6.远程调试应用程序
- 将JAR文件复制到远程计算机甚至同一台计算机上的适当位置,调用调试服务器,然后将客户端附加到该文件。 简单的Java应用程序可以充当调试服务器或客户端。 根据配置,您可以在Eclipse中选择Socket Attach或Socket Listen连接类型。 在以下两个部分中,学习如何将应用程序作为服务器或客户端运行。
目标VM充当调试服务器
以下示例在远程端调用Java应用程序,充当调试服务器,并侦听端口8000上的套接字连接。目标VM将被挂起,直到调试器连接为止。
清单6. Eclipse中用于套接字附加模式的VM调用示例
java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address="8000" -jar
test.jar
使用远程启动配置启动Eclipse并指定远程应用程序的目标VM地址。 为此,请单击“运行”>“调试配置” ,然后在Eclipse菜单中双击“ 远程Java应用程序 ”。 在新创建的启动配置中,指定目标应用程序的IP和端口。 要在同一台计算机上运行远程应用程序,只需将主机IP指定为localhost或127.0.0.1。
图4.套接字连接的配置
选择“ 允许终止远程VM”选项以终止在应用程序调试期间要连接的VM。
图5. Eclipse中的Terminate按钮
目标VM充当调试客户端
第二个示例是使用一个简单的Java应用程序充当调试客户端,而调试器前端充当调试服务器。 Eclipse使用套接字侦听模式连接类型进行侦听。 必须提前启动调试前端才能侦听特定端口。 图6显示了用于设置侦听的示例配置。
图6.侦听套接字的配置
单击Eclipse Debug按钮,状态栏将显示消息“正在等待vm连接到端口8000 ...”。看到该消息后,启动远程应用程序。 清单7显示了如何使用主机127.0.0.1上端口8000上的套接字将Java应用程序作为调试客户端调用并将其附加到正在运行的调试器应用程序。
清单7.用于Eclipse中套接字监听连接的VM调用示例
java -Xdebug -Xrunjdwp:transport=dt_socket,address=127.0.0.1:8000,suspend=y
-jar test.jar
如果一切顺利,将显示debug透视图以支持应用程序调试,并且远程Java应用程序的执行将正常停止。 这类似于我们在本地调试中执行的步骤3(请参见图3)。 此时,您可以使用标准的调试功能,例如设置断点和值,执行步骤等。
结论
本文说明了如何使用Eclipse内置的远程Java应用程序配置类型来远程执行应用程序调试。 它介绍了如何设置Java应用程序以调用远程调试,并帮助您了解Eclipse提供的连接器。 最后,您学习了如何将此技术应用于您的项目。
翻译自: https://www.ibm.com/developerworks/java/library/os-eclipse-javadebug/index.html