eclipse远程调试

原帖地址1

原帖地址2

原帖地址3

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

先决条件

启动配置类型

启动配置 保存一组用于启动程序的属性。启动配置类型是一种可以在 Eclipse 平台上启动的独特程序。

如果您还没安装该程序,请下载 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 简介

  • JDI— Java 调试接口(Java Debug Interface)
  • JDT— Java 开发工具(Java Development Tools)
  • JDWP— Java 调试网络协议(Java Debug Wire Protocol)
  • JPDA— Java 平台调试器架构(Java Platform Debugger Architecture)
  • JVM— Java 虚拟机(Java Virtual Machine)
  • JVMDI— JVM 调试接口(JVM Debug Interface)
  • JVMTI— JVM 工具接口(JVM Tool Interface)
  • VM— 虚拟机(Virtual Machine)

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 是一个高级的接口,它定义用于远程调试的信息和请求。下面给出了调试器的架构。

清单 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 程序,甚至还可以通过网络进行远程调试。

在讨论调试场景之前,我们先了解 JPDA 规范中的两个术语:连接器和传输。连接器是一个 JDI 抽象,用来在调试器应用程序和目标 VM 之间建立连接。传输定义应用程序如何进行访问,以及数据如何在前端和后端之间传输。连接器 “映射” 到可用的传输类型和连接模式。在 Sun 的 JPDA 参考实现中,为 Microsoft® Windows® 提供了两个传输机制:套接字传输和共享内存传输。可用的连接器:

  • 连接套接字连接器
  • 连接共享内存连接器
  • 监听套接字连接器
  • 监听共享内存连接器
  • 启动命令行连接器

在调试器应用程序和目标 VM 之间建立连接时,有一端将用作服务器并监听连接。随后,另一端将连接到监听器并建立一个连接。通过连接,调试器应用程序或目标 VM 都可以充当服务器。进程之间的通信可以在同一个机器或不同的机器上运行。

要远程调试 Java 程序,难点不是在调试器的前端,而是远程 Java 后端。不幸的是,Eclipse 帮助系统中为这方面提供的信息并不多。事实上,JDI 和 JVMTI 是分别由 Eclipse 和 Java 运行时环境实现的。我们仅需要考虑 JDMP,因为它包含与 JVMTI 和 JDI 进行通信所需的信息。JDWP 包含许多参数,用于为远程 Java 应用程序调用所需的程序。以下是本文用到的一些参数。

-Xdebug
启用调试特性。
-Xrunjdwp:<sub-options>
在目标 VM 中加载 JDWP 实现。它通过传输和 JDWP 协议与独立的调试器应用程序通信。下面介绍一些特定的子选项。

从 Java V5 开始,您可以使用 -agentlib:jdwp 选项,而不是 -Xdebug-Xrunjdwp。但如果连接到 V5 以前的 VM,只能选择-Xdebug-Xrunjdwp。下面简单描述 -Xrunjdwp 子选项。

transport
这里通常使用套接字传输。但是在 Windows 平台上也可以使用共享内存传输。
server
如果值为 y,目标应用程序监听将要连接的调试器应用程序。否则,它将连接到特定地址上的调试器应用程序。
address
这是连接的传输地址。如果服务器为 n,将尝试连接到该地址上的调试器应用程序。否则,将在这个端口监听连接。
suspend
如果值为 y,目标 VM 将暂停,直到调试器应用程序进行连接。

要获得每个调试设置的详细解释,请参考 JPDA 文档(参见 参考资料)。

清单 2 是一个示例,显示如何在调试模式下启动 VM 并监听端口 8765 的套接字连接。

清单 2. 作为调试服务器的目标 VM
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8765

清单 3 显示如何使用位于 8000 端口的主机 127.0.0.1 上的套接字连接运行中的调试器应用程序。

清单 3. 作为调试客户机的目标 VM
-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 中共有两个连接器:

  • Socket Attach
  • Socket Listen

对于监听套接字的连接器,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 来修改设置。

图 1. Eclipse 中的调试选项
eclipse远程调试_第1张图片

现在,我们已经准备好远程调试应用程序。我们分步执行:

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."); 这行中设置断点。
图 2. 在 Eclipse 中设置断点
eclipse远程调试_第2张图片
3. 从本地调试应用程序
在调试应用程序之前,确保已经为项目启用图 1 中描述的调试选项。从本地调试应用程序是没有必要的,但是这可以确保是否所有调试信息都可用。右键单击 Java 项目,并选择 Debug As,然后选择 Java Application(参见图 3)。如果应用程序在断点处停止执行,则表明调试信息正确显示。这时,可以继续使用这些调试特性,比如显示调试堆栈、变量或断点管理等等。
图 3. 从本地调试应用程序
eclipse远程调试_第3张图片
4. 导出 Java 项目
我们将使用这个应用程序作为调试目标。右键单击 Java 项目,选择 Export,然后选择 Java,最后选择 JAR fileRunnable JAR file 导出项目。将在指定的位置生成 JAR 文件。注意,如果 Java 源代码与目标应用程序不匹配,调试特性将不能正常工作。
5. 手动运行 Java 应用程序
打开控制台手动启动应用程序,确保正确配置了 Java 运行时环境。
清单 5. 调用 Java 应用程序的示例
java -jar test.jar
6. 远程调试应用程序
将 JAR 文件复制到远程计算机或同一台计算机上的适当位置,调用调试服务器,然后为它添加一个客户机。简单的 Java 应用程序就可以充当调试服务器或客户机。您可以在 Eclipse 中选择 Socket AttachSocket Listen 连接类型,这取决于特定的配置。接下来的两个小节将学习如何将应用程序作为服务器或客户机运行。

作为调试服务器的目标 VM

下面这个示例远程调用 Java 应用程序作为调试服务器,并在端口 8000 监听套接字连接。目标 VM 将暂停,直到调试器连接。

清单 6. Eclipse 连接套接字模式下的 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。

图 4. 连接套接字连接的配置
eclipse远程调试_第4张图片

选择 Allow termination of remote VM 选项终止在应用程序调试期间连接的 VM。

图 5. Eclipse 中的 Terminate 按钮
eclipse远程调试_第5张图片

作为调试客户机的目标 VM

第二个示例使用一个简单的 Java 应用程序作为调试客户机,并且调试器前端作为调试服务器。Eclipse 使用套接字监听模式连接类型进行监听。必须先启动调试前端来监听特定的端口。图 6 给出一个用于设置监听的示例配置。

图 6. 监听套接字连接的配置
eclipse远程调试_第6张图片

单击 Eclipse Debug 按钮,状态栏将显示消息 “waiting for vm to connect at port 8000...”。看到这个消息后,启动远程应用程序。清单 7 显示了如何将 Java 应用程序作为调试客户机并调用它,然后使用端口 8000 上的主机 127.0.0.1 的套接字将其连接到一个正在运行的调试器应用程序。

清单 7. Eclipse 监听套接字连接模式中的 VM 调用示例
    java -Xdebug -Xrunjdwp:transport=dt_socket,address=127.0.0.1:8000,suspend=y 
         -jar test.jar

如果一切进行顺利,将会显示一个调试透视图帮助调试应用程序,并且远程 Java 应用程序将正常停止。这类似于步骤 3 中的本地调试(参见图 3)。在这里,您可以使用标准的调试特性,比如设置断点和值、单步执行等。

本文演示如何使用 Eclipse 内置的远程 Java 应用程序配置类型对应用程序执行远程调试。介绍了如何设置 Java 应用程序以调用远程调试,并帮助您理解 Eclipse 提供的连接器。最后,您还学习了如何将这些技术应用到项目中。


以下谈论的是Applet的远程调试技术,实际上对于其他java程序一样适用,只需要使用文中参数启动java程序即可

Java远程调试方式,两种方式进行远程调试

上面的表示是Eclipse配置为Socket Listen方式,下面的是Socket Attach方式

对于远程程序上图表示主动链接调试器,下图表示远程程序正常运行 允许调试器连接jvm

eclipse远程调试_第7张图片

Eclipse配置: 菜单(Eclipse):Run-->Debug Configurations打开调试配置面板,如图配置

eclipse远程调试_第8张图片

左侧新建一个远程调试

左侧Project:源代码工程

左侧Connection Type:调试方式

左 侧Connection Properties:配置与Connection Type相关的调试连接属性

Standard(Socket Attach)方式调试:

左侧Connection Type:Standard(Socket Attach)

左侧Connection Properties:

host:192.168.228.7 (远程java主机ip)

Port: 9998 (远程java配置的调试端口)

Console代码
  
  
  
  
  1. 远程java程序配置     
  2. /prog/java/jdk/bin/jcontrol     
  3. #window系统在(控制面板->其他程序->java)打开"Java Control Panel"配置对话框     
  4. #在打开远程java主机的"Java Control Panel"配置对话框 进行配置     
  5. #-Xdebug -Xrunjdwp:transport=dt_socket,address=9998,server=y,suspend=n     
  6. #如图   
远程java程序配置
/prog/java/jdk/bin/jcontrol
#window系统在(控制面板->其他程序->java)打开"Java Control Panel"配置对话框
#在打开远程java主机的"Java Control Panel"配置对话框 进行配置
#-Xdebug -Xrunjdwp:transport=dt_socket,address=9998,server=y,suspend=n
#如图

eclipse远程调试_第9张图片

先启动远程java程序 然后 启动Eclipse远程调试,现在可以正常调试系统了

缺点 :只有java程序启动后才能进行调试,无法调试java程序的启动过程,如果要全程调试需要使用下面的方式

优点 :可以随时连接到远程java程序进行调试,没尝试过多机同时调试一个远程java 

Standard(Socket Listen)方式调试:

左侧Connection Type:Standard(Socket Listen)

左侧Connection Properties:配置Port为9999

远程java程序配置

Sh代码
  
  
  
  
  1. /prog/java/jdk/bin/jcontrol     
  2. #window系统在(控制面板->其他程序->java)打开"Java Control Panel"配置对话框     
  3. #在打开远程java主机的"Java Control Panel"配置对话框 进行配置     
  4. #-agentlib:jdwp=transport=dt_socket,suspend=y,address=192.168.228.7:9999    
  5. #address:Eclipse程序所在的主机的IP和调试端口     
  6. #如图   
/prog/java/jdk/bin/jcontrol
#window系统在(控制面板->其他程序->java)打开"Java Control Panel"配置对话框
#在打开远程java主机的"Java Control Panel"配置对话框 进行配置
#-agentlib:jdwp=transport=dt_socket,suspend=y,address=192.168.228.7:9999
#address:Eclipse程序所在的主机的IP和调试端口
#如图

eclipse远程调试_第10张图片

先启动Eclipse远程调试,然后启动远程java程序 现在可以正常调试系统了

缺点 :不能随时连接到远程java程序进行调试

优点 :可以调试java程序启动过程


今天决定做件有意义的事,写篇图文并茂的blog,为什么要图文并茂?因为很多事可能用语言也说不明白,从以前我发表的一篇文章可以看得出来, http://blog.csdn.net/sunyujia/archive/2008/03/23/2211109.aspx 我的朋友们普通反应看完后觉得不知所云,可能是我写的太简单,下面步入正题。
       什么是远程调试,就是在A机器上利用Eclipse单步跟踪调试B机器上的Web应用,当然调试A机器上Web应用也是没有问题的,90%我都是调试本机的Web应用,远程调试的意义我想我不用说了,大家都会想到它的好处,你可以在本地调试非本地测试环境上的应用,这是件多么美妙的事,所以我就不说它的好处了,那么本地调试呢,我喜欢本地调试也采用下面要介绍的方法,为什么不用myeclipse,WTP,TomcatPlugin等。
         下面我阐述下在eclipse中启动Web应用的缺陷:
我本身是非常喜欢使用Myeclipse 做WEB部署的,但是我不喜欢使用Myeclipse启动tomcat,当然WTP,TomcatPlugin等也不喜欢,使用Myeclipse做部署的好处就是非常灵活,不仅可以部署到Web应用里面还可以任意部署到某一指定路径下。但是使用Myeclipse启动tomcat的话,有如下问题:
         a.卡,比较慢,尤其是同时启动多个应用.
         b.如果断点比较多的时候例如100多个,必须把每个不需要使用的断点先禁用掉或干脆删掉,也就是说web应用启动的时候就已经决定了是debug模式还是run模式。中间不可以切换。
c.一旦eclipse死掉了,web应用也就断掉了。
d.对于程序来说相对路径,类加载路径都是和系统正式运行的情况下完全不同的(要视具体插件而论,每个插件的部署方式都不太一样),即和Web应用独立运行的相对路径和类加载环境有差异,当然熟练的老手可以轻松搞定,但是就目前国内情况看,很多初学者在这个问题上还是很苦恼的。
e.顺便说一句和本话题无关的,eclipse的console并不能完全模拟cmd控制台,一些流操作会有问题。例如:PushbackInputStream
那么使用远程调试的方法做本地调试有什么好处呢?
a.       运行速度比较好。
b.       运行期间可以使用eclipse连接web应用做调试,调试完成后可以断开连接,需要调试的时候可以再重新进行连接,断点的禁用功能可能就很少派上用场了,因为相对于在debug模式和run模式间自由切换。
c.       Web应用是独立运行的,不用担心eclipse死掉即玩完了。
d.       从开发到上线运行,环境一直可以保持一致。
说了半天,没有使用过的人可能还是不了解,没关系,可以看完下面的,再回过头看上面的。
下面我举一个小例子介绍如何进行远程调试.
环境:tomcat,Eclipse,做远程调试不需要任何插件。当然可以使用MyEclipse把Web应用部署到tomcat上面,注意只是部署,一般来讲使用远程调试就不需要配置MyEclipse的Web Server了,MyEclipse在这里只起到一个copy文件的作用,好在现在Myeclipse可以随意指定目录copy了。即 Deployment 对话框中的Custom Location,在这里推荐大家一个copy文件的小插件,有了这个插件就不需要Myeclipse部署了。
FileSync plugin for Eclipse http://andrei.gmxhome.de/filesync/index.html 这个插件的作者还写了很多其他好用的插件,大家可以顺便看下。
       这次例子的源码很简单:
Jsp 源码如下index.jsp
<% com.syj.test.DebugTest.test( "sunyujia test" ); %>
Hello Remote Debug
DebugTest 类的 test 方法中做个断点既可测试
 
下面按步骤进行讲解
1.    web 应用部署到 Tomcat webapp 目录下
2.    修改 Tomcat/bin/startup.bat 文件,在最前面加上如下代码
SET CATALINA_OPTS=-server -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000
注意上面命令 必须写成一行中间不能有换行, - 前是空格 - 后是非空格,由于显示器分辨率不同,该文章在显示的时候可能会有换行的情况。
更多 Web 服务器远程调试参数可参见
http://blog.csdn.net/sunyujia/archive/2008/03/23/2211109.aspx
3.必须先启动Tomcat启动tomcat/bin/ startup.bat参下图
eclipse远程调试_第11张图片
4.在 com.syj.test.DebugTest.test 方法中设置断点
5 在eclipse中配置debug,配置完成后点击debug按钮。如图:
eclipse远程调试_第12张图片
6.打开浏览器访问在第1步部署的web应用,访问index.jsp
7.当浏览器访问index.jsp时,由于调用了 com.syj.test.DebugTest.test ,又因在 test 方法中设置了断点,所以程序会被断点拦截,如图:
eclipse远程调试_第13张图片
8.不需要调试的时候点击断开,需要调试的时候再点击debug,非常方便,当调试过程中出现引用非本project的源码时(例如跟踪到tomcat里面或spring,hibernate里面),会提示找不到源码,点击相应提示的按钮(到时候editor区只有一个按钮,所以大家就不要问哪个按钮了)可以添加源码继续调试,或在配置debug前就把需要的源码都添加上,在source选项卡里面,因为具体的基本调试这方面知识不属于本话题讨论范围内,就不过多介绍了。
远程调试就介绍到这里吧。打了这么多字还是比较辛苦的,转载请注明出处,谢谢!


你可能感兴趣的:(eclipse远程调试)