自定义的ant Task如果比较复杂,如何使用ant运行的build.xml调试对应的java代码?
思路一,ant本身是个批处理,逻辑也是用java实现的,自定义的类Task是以refect的方式由java虚拟机加载执行的。我们用的命令 ant -f xxx.xml target实际是调用了一个脚本,并把build文件和target作为参数传给ant的主函数。因此完全可以在eclipse中完成这些动作,并启动调试或者单纯运行。
在一个拥有build.xml文件的java工程(既包含要调试的task的工程)中,针对工程debug-》debug configurations,工程选择当前工程,主函数org.apache.tools.ant.Main,也就是ant的主函数。
选择argument选项卡,在program argument中填写你本来想运行的ant参数比如: -f "D:\xxx\build.xml" debugtargetname;
在classpath中bootstrap entries中添加ANT_HOME\lib目录下的ant.jar和ant-launcher.jar。
在源代码中打上断点即可启动调试。
其他的配置没什么特殊的,将要调试的工程export出一个jar,比如test.jar,放置在和build.xml同目录下。具体的build.xml中
<target name="debugtarget"> <taskdef name="debugtest" classname="com.anttest.ForTestTask" classpath="./test.jar"/> <debugtest/> </target>
这个方法要配置很多的环境信息和参数,且不利于多次调试,另外一种方法是利用java的远程调试来达到调试的目的。
参考这篇文字,http://www.ibm.com/developerworks/cn/opensource/os-eclipse-javadebug/
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 是一个高级的接口,它定义用于远程调试的信息和请求。下面给出了调试器的架构。
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 应用程序调用所需的程序。以下是本文用到的一些参数。
从 Java V5 开始,您可以使用 -agentlib:jdwp 选项,而不是 -Xdebug 和 -Xrunjdwp。但如果连接到 V5 以前的 VM,只能选择 -Xdebug 和 -Xrunjdwp。下面简单描述 -Xrunjdwp 子选项。
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8765
作为调试客户端的目标VM
-Xdebug -Xrunjdwp:transport=dt_socket,address=127.0.0.1:8000
连接套接字连接的配置
选择 Allow termination of remote VM 选项终止在应用程序调试期间连接的 VM。
监听套接字连接的配置
单击 Eclipse Debug 按钮,状态栏将显示消息 “waiting for vm to connect at port 8000...”。看到这个消息后,启动远程应用程序。清单 7 显示了如何将 Java 应用程序作为调试客户机并调用它,然后使用端口 8000 上的主机 127.0.0.1 的套接字将其连接到一个正在运行的调试器应用程序。
下面用java远程调试来调试ant
Java的远程调试JDPA是基于JDWP协议的一种交互式调试方式,最大的特点是VM的运行环境和调试环境相互独立。这样就可以很好的解决运行和调试的环境问题。
要实现远程调试,需要在server端的虚拟机参数中加入:
-Xdebug -Xrunjdwp:transport=dt_socket,address=5050,server=y,suspend=y
即:使用端口的方式进行JDWP通讯,端口为5050,采用挂起的方式,只有客户端连上才启动虚拟机。
对于ant来说,此参数无疑要加到启动ant主类的参数中。我们分析ant.bat看到:
"%_JAVACMD%" %ANT_OPTS% -classpath "%ANT_HOME%/lib/ant-launcher.jar" "-Dant.home=%ANT_HOME%" org.apache.tools.ant.launch.Launcher %ANT_ARGS% %ANT_CMD_LINE_ARGS%
而%ANN_OPTS%这个环境变量在批处理之前并没有得到设置,看来这就是ANT留给我们的操作参数变量,创建一个debug_ant.bat
set ANT_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,address=5050,server=y,suspend=y
call ant %*
用bebug_ant.bat来替换ant.bat就可以在不影响任何其它环境变量的情况下,启动远程调试server。
2.2 创建远程服务Client
用eclipse打开你的自定义Task所在的工程,打开Debug configuration,新增Remote Java Application
选择connection Type: Standard(SocketAttach)
选择connection Properties:
Host: local host
Port: 5050
2.3 开始调试
在对应的位置用debug_ant来替换ant执行相关的xml脚本,此时虚拟机会挂起。
在eclipse的代码相应位置设置好断点,采用刚刚创建的configuration进行调试。
此时ant的虚拟机将开始执行,并会在断点相应的位置上做出响应。
参考:http://blog.csdn.net/CaesarZou/article/details/5672415
http://blog.csdn.net/chyroger/article/details/6339158