原文,还是中文的哟~:
http://www.ibm.com/developerworks/cn/opensource/os-eclipse-javadebug/
我基本是参考了这篇文章,但是整理了一下结构,且更倾向于实践。
远程调试的意义所在不用多说,想象一下自己是在一个小型移动设备上开发java程序,比如手机。
咱不可能login到手机上打开eclipse调试吧?在windows上用eclipse调试程序,程序却又不是真的在手机上运行。
如果程序在手机上运行出错,只有在手机上debug代码,才能发现问题所在。否则咱就只能靠猜了。
老实说文章开始讲述原理的部分没看懂。但是不管怎样,咱只要试成了就行了~
过程其实很简单:
1,新建一个简单的java程序,并且打个断点。
2,在eclipse上配置remote java application。
3,在remote端,用特殊JVM选项 launch程序。然后就OK了。
下面一步一步的说明。
在eclipse中新建一个java项目 HttpContent。然后新建一个类httpContent,代码内容是:
package com.test.httpContent;
public class httpContent {
public static void main(String args[]){
System.out.println("test");
}
}
在System.out.println("test");这行打一个断点。
然后在eclipse里运行一下,确定没问题后,导出成jar包,例如httpContent.jar (怎么做参考原文)。
将jar包考到目标目录下,通常是远程机器上。这里我们是做测试所以就随便找个临时目录好了。
然后运行程序看看是否工作正常:
java -jar httpContent.jar
打印出test就OK了。
在eclipse中点击->run ->debug configurations
然后右击remote java application->new 可以看到如下窗口:
说明:
Name就随便取啦,都行。
Project选择我们刚刚新建的HttpContent。
Connection Type据原文解释是指将远程机器,例如手机,作为debug host 还是 debug client。有时因为例如手机的性能问题,最好将手机作为debug client。
Connection Properties因为我们是在本地做测试,所以选本机就行了。
设置完后,先不要点debug,放在这儿。
进入windows命令行,找到第一步放置好的jar包,运行:
D:\Fun>java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address="8000" -jar httpContent.jar
可以看到下列输入:
Listening for transport dt_socket at address: 8000
此时回到eclipse,点击Debug。然后就能看到,eclipse进入了debug模式,停在了断点处。
同时回到windows命令行,可以看到httpContent程序悬停在那里不动了。
如果这时在eclipse中按F6,代码往下运行System.out.println("test");,可以看到windows 命令行立即输出了一个“test”。
在eclipse中停止运行,windows 命令行马上也停止。过程如下:
D:\Fun>java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address="8000" -jar h
ttpContent.jar
Listening for transport dt_socket at address: 8000 //回车即可看到这行提示
Debugger failed to attach: recv failed during handshake: Connection reset by peer //如果迟迟没有在eclipse中开始debug,则会提示没有debugger连接,时间长了还会超时
test //在eclipse中按F6运行System print后会打印出这句
D:\Fun> //程序运行完毕或在eclipse中终止运行后,JVM退出。
成功~此时就可以正常调试了~
New update:
其实观察一下这个过程,就能明白是java虚拟机提供了debug接口:当用-Xdebug -Xrunjdwp 启动java程序时,该程序运行时就能接受外部的debugger的控制(本例中的debugger就是eclipse)。
下面大概看一下launch程序时涉及的几个java vm的选项:
也就是说,其实-Xdebug是使用了jdb(java debugger)。jbd有两中使用方式:
1,直接在命令行中launch程序
>jdb MyClass 这时会launch一个单独的JVM来运行myclass。此时在一个单独的进程里debug。
或者和本文中一样:
>java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address="8000" -jar MyClass
此时jdb is connecting to an existing VMinstead of launching a new one。
2,launch程序之后,就需要将debugger attach到JVM上。
> jdb -attach 8000
或者和本文一样,就是修改了eclipse中的配置然后将eclipse作为debugger attach到JVM上。
可以参考下面这篇更详细一点的文章:
http://www.eclipsezone.com/eclipse/forums/t53459.html
超级详细原理介绍可以参考这篇官方文档:
http://docs.oracle.com/javase/6/docs/technotes/guides/jpda/conninv.html
最后提一点,对于所有的java程序都可以使用jdb。例如在maven中运行UT时,使用的surefire插件也是一个java程序。
当我遇到在eclipse中直接运行UT case可以成功,但是用maven运行UT却总是失败时,就可以用jdb launch“maven test”,从而debug在maven中运行UT时到底发生了什么事。
下面的文章是参考:
http://maven.apache.org/plugins/maven-surefire-plugin/examples/debugging.html
常犯的错误:
从上面的过程可以看出,eclipse里的代码和远端launch的jar必须保持一致。否则会出现在eclipse中debug的时候,那些jar包里没有的代码永远都debug不到。
当发现debug的时候有些语句怎么都断不住的时候,赶紧去怀疑是不是这个问题啦~