转载于:http://www.blogjava.net/zjrstar/archive/2008/07/06/212914.html
翻译文章网址:http://www.jacoozi.com/index.php?option=com_content&task=view&id=119&Itemid=134
试图修复服务器端的Java问题,花费大量时间获取问题源的经历不知道发生了多少次?调试器可以显著地缩短错误发现时间而且使调试过程更加变得享受。这篇文章将探索如何在Eclipse中使用远程调试器。
文章内容:
Java调试器
调试Weblogic
调试IBM WebSphere 5.x/6.x
调试JBoss
在JBoss中热交换代码
调试Tomcat
调试JSP页面
调试器验证
参考
系统信息
Java调试器
Java调试器(jdb)是一个动态的,可控的,基于任务的调试工具。它帮助找到并修复本地的和服务器端的Java语言的臭虫。为了在J2EE应用服务器中使用jdb,首先必须让eclipse中的调试成为可用,而且将通过JPDA端口(默认端口是1044)的调试和服务器关联在一起。
J2EE服务器缺省的JPDA选项如下:
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=1044
Jdb参数指定调试器操作方式。例如transport=dt_socket告诉JVM调试器将会通过socket连接,然而address=1044通知端口号是1044.类似地,如果你设置suspend=y,JVM将会以挂起模式(suspended mode)启动,保持挂起状态直到调试器关联上它。如果想一启动JVM就想启动调试,那么这将是有帮助的。
调试Weblogic
调试Weblogic和调试其他Java远程应用没有什么区别。需要确保启动Weblogic时设置了必须的调试参数,而且连接了调试器。就Weblogic8.1来说,需要增加下列参数在启动脚本中。Weblogic提供多个启动脚本(*.sh和*.cmd),脚本位置在BEA_HOME/weblogic81/server/bin目录下。
1. 找到startWSL.cmd并且增加下列变量DEBUG_OPTS:
set DEBUG_OPTS = -Xdebug -Xrunjdwp:transport= dt_socket,address=1044,server=y,suspend=n
2. 接下来,插入新变量在Weblogic启动命令中,放在"%JAVA_HOME%/bin/java"后和其他参数前。
3. 启动脚本类似于下面的脚本:
"%JAVA_HOME%/bin/java" %DEBUG_OPTS% %JAVA_VM% %MEM_ARGS% %JAVA_OPTIONS%-Dweblogic.Name=%SERVER_NAME% -Dweblogic.management.username= %WLS_USER%-Dweblogic.management.password= %WLS_PW% -Dweblogic.management.server= %ADMIN_URL%-Dweblogic.ProductionModeEnabled= %PRODUCTION_MODE%-Djava.security.policy= "%WL_HOME%/server/lib/weblogic.policy" weblogic.Server
调试IBM WebSphere 5.x/6.x
1. 打开WebSphere 5.X/6.X控制台
2. 打开Servers | Application Servers | [SERVERNAME] | Process Definition | Java Virtual Machine
3. 注册Debug Mode
4. 在Debug arguments域中编辑参数。可以粘贴下面的的代码,使用相同的1044端口从eclipse调试:
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=1044
调试JBoss
除了需要修改JBOSS_HOME/bin下的run.bat/run.sh外,其他和WebLogic相同。
Linux用户可以看到类似于如下的配置:
$ cd /var/jboss4/bin
$ sh ./run.sh
=========================================================================
JBoss Bootstrap Environment
JBOSS_HOME: /var/jboss4
JAVA: /usr/java/j2sdk1.4.2_06/bin/java
JAVA_OPTS: -server -Xms128m -Xmx128m -Dprogram.name=run.sh
DEBUG_OPTS = -Xdebug -Xrunjdwp:transport= dt_socket,address=1044,server=y,suspend=n
CLASSPATH: /var/jboss4/bin/run.jar:/usr/java/j2sdk1.4.2_06/lib/tools.jar
=========================================================================
JBoss中的热交换代码(Hot Swapping Code)
假如JBoss根目录在C:/JBoss,应用程序的classpath是C:/classes/myapp。通过设置这个目录为项目输出目录来告诉Eclipse编译应用程序到这个目录下。这样基本上可以工作了,但是有点隐患。
如果每次都使用Ant脚本来build-clean,或许想确保输出目录的内容不要偶然地被Eclipse清除掉。由于Eclipse有项目的清除功能,这种功能能容易重击整个目录从而仅仅得到类文件。为此,为了保持Ant生成的文件和Eclipse将生成的*.class文件在一起,你必须告诉Eclipse你的输出目录。
1. 首先设置Java项目输出目录。假设JBoss应用程序的classpath在Eclipse工作空间之外,这样设置一个链接的目录将是个不错的选择。
2. 打开File | New | Folder。
3. 输入classes作为目录名字,点击Advanced,指定新目录为C:/classes/myapp。
4. 在项目属性页,修改输出目录为新创建的classes目录。点击Project | Properties | Java Build Path,在Default output foder中写入如下值。
5. 打开Window | Preferences... | General | Workspace,选中Build automatically。
6. 最后,告诉Eclipse不要每次编译项目的时候删除输出目录的其他文件。依然在Preferences中打开Java | Compiler | Building,不要选中Scrub output folders when cleaning projects。这就是说,现在每次你保存Java文件,Eclipse会重新编译它而且JBoss也会重新加载它。
调试Tomcat
调试Tomcat非常类似于Weblogic和JBoss,但是需要修改TOMCAT_HOME/bin下的catalina.bat/catalina.sh文件。
Tomcat是一个特殊的情况,因为它能够调试和发布置换热代码(hot code)。
在Eclipse中使用Sysdeo Tomcat Plugin
Sysdeo是Eclipse下小而强大的Tomcat插件。和其他插件一起使用Sysdeo将会让你调试Tomcat和重新加载上下文。
1. 首先从Sysdeo网站下载插件
2. 解压文件到ECLIPSE_HOME/plugins目录
3. 启动Eclipse,打开Window | Preferences... | Tomcat.
4. 在插件参数页,指定Tomcat版本和主目录。在Tomcat中有两种声明上下文的方式。比较新的方式是在TOMCAT_HOME/conf/Localhost下创建上下文文件。在Preferences | Tomcat | Context declaration mode下选择Context files,设置Context files为自动选择(Tomcat 5.5.12)
5. 关闭Preferences。打开任意一个透视图,将能看到工具栏上3个cat按钮。启动Tomcat,点击第一个图标。这将创建一个新服务器进程,Eclipse调试器将会自动附加上去。调试模式可以通过Preferences页来修改。
6. 如果打算调试代码,也可以增加项目到Tomcat源和classpath查找路径。需要关注的一点,就是插件将会改变Tomcat输出到Eclipse控制台。另一个重要的事情就是附加或者预先将JAR文件放到classpath或者传递JVM参数到启动器。这些可以在插件参数页上设置。
配置可重新加载的Tomcat上下文
如果你无论如何也不想使用Sysdeo,那么也可以很容易的调试Tomcat:
首先为应用创建一个新的Tomcat上下文,打开TOMCAT_HOME/conf/Catalina/localhost,创建一个新文件,例如myapp.xml。这将成为你url的一部分,因此如果你要访问你的程序,你可以输入http://localhost:8080/myapp
输入下面的内容在myapp.xml
<Context docBase="c:/eclipse_workspace/myapp/WebRoot" path="/HelloWorld"/
假设你在c:/eclipse_workspace/myapp/WebRoot中有一个包含WEB-INF的web应用
创建两个环境变量:
C:/>set JDPA_ADDRESS=1044
C:/>set JDPA_TRANSPORT=dt_socket
现在可以用下面的调试参数来启动Tomcat
C:/Tomcat-5.5.12/bin/>catalina jdpa start
使用Eclipse通过1044来连接Tomcat
在Tomcat中热交换代码和自动上下文重载
在一些情况下,调试需要包含一些在变化的类,当然希望调试器用的是最新的变动代码而且准确无误的重新加载它们。这是最正常的情况了,但是不是总都这样。为了重新加载上下文环境,你必须定义上下文环境为reloadable。
打开myapp.xml修改它:
<Context docBase="c:/eclipse_workspace/myapp/WebRoot" path="/HelloWorld" reloadable="true"/>
现在上下文将会在每次改变任何Java文件的时候都会重载。注意加载时需要花费一些时间的,尤其如果应用程序比较大的话。类似的,如果你有比较复杂的启动servlet,你可能希望让自动重载无效,因为即使是最小的变动都会导致整个环境重新加载。
调试JSP页面
在Eclipse中调试JSP,可以通过好几种方式。最简单的方法就是使用一些商业插件用于在建支持JSP调试。这样的插件有MyEclipse和另外一种Nitrox。除了提供JSP调试外,这些商业插件还提供很多其他功能,例如数据库资源管理器,XML编辑器,UML和ERD图等等。这些插件的副作用是环境变得越来越大,反应也会变慢。从我的经历来看,这些插件导致Eclipse相当的慢,而且有时环境变得很不稳定。类似的,这些耗费大内存的插件是导致频繁内存溢出异常和随后的环境崩溃的原因。长话短说,我最终决定还是使用最基本的。当我意识到调试JSP可以不用任何插件时,建立这个过程稍微多会花些时间,但是回报的却是快速和稳定的环境。
在知道了JSP被转化为Java文件后,调试JSP变得很容易。这个转化发生在运行时,JSP只存在在它们被javac编译前。在这个例子中我将使用JBoss,然而可以使用类似的技术到其他服务器上。由于JBoss使用jasper和javac来生成和编译Java,因此首先创建一个用于Java工程,其源代码指向JBoss JSP输出目录。这个工程和普通的Java工程有一个显著的区别:源目录的大小将会不断的变化,主要是因为JBosss要重新编译JSP。
跟随下面的步骤来建立Eclipse的JSP调试:
1. 启动JBoss
2. 定位到JBoss编译JSP的地方。这主要依赖于你发布是WAR包和你的真实的服务器配置,你可以找到类似于下面的位置:JBOSS_HOME/server/j2ee/work/jboss.web/localhost/myapp
3. 启动Eclipse,打开File | New | Other....选择Java Project点击Next。
4. 在New Java Project页,输入项目名称,例如my_jsp.其他想保持缺省状态,点击Finish。
5. 创建一个新目录链接到JBOSS_HOME/server/j2ee/work/jboss.web/localhost/myapp。这个目录将会在以后成为项目源代码目录
6. 使src成为源代码目录。打开File | New | Source Folder
7. 点击Browse而且选择src,点击Finish。保持和下面的对话框一致。
8. 在上面的对话框里,修改项目输出目录为src。
9. Eclipse将会试图编译my_jsp,但是将会看到许多问题。为了项目能够正确编译两个主要问题必须解决。首先,jasper库必须加入项目的classpath中,第二必须指出Java代码工程my_java_code(假设分离Java项目主机域类和servlet)。
10. 打开Project properties,增加下面的库到classpath:
11. JBOSS_HOME/server/j2ee/deploy/jbossweb-tomcat50.sar/jasper-runtime.jar
12. JBOSS_HOME/server/j2ee/lib/javax.servlet.jsp.jar
13. 而且,点击Project页增加my_java_code到classpath。现在my_jsp工程classpath如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry excluding="src/" kind="src" path=""/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="lib" path="C:/jboss-4.0.1sp1/server/j2ee/deploy/jbossweb-tomcat50.sar/jasper-runtime.jar"/>
<classpathentry kind="lib" path="C:/jboss-4.0.1sp1/server/j2ee/lib/javax.servlet.jsp.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/my_java_code"/>
<classpathentry kind="output" path="src"/>
</classpath>
14. 打开Project | Build Project。这次编译应该没问题了。
15. 启动JBoss。使用Eclipse调试器开始调试会话
16. 打开一个浏览器访问几个页面。回到Eclipse,右键点击my_jsp选择Refresh。你将会看到多出Java的类文件。
17. 在任何类上双击,打开_jspService方法,设置一个断点。返回到浏览器点击Refresh
JSP页面将会关联上来,你就可以进入代码了。当调试器静进入响应JSP页面的Java类,JSP编辑器将会自动链接起来,你将会自动进入JSP代码的感觉。所有变量将会被赋值,然后你真实的在调试任何Java类。现在大功告成了。
调试器验证
现在可以在调试模式下启动你的应用程序。只需要确保服务器正在监听1044端口,你可以运行netstat /a.你将会在打开的端口列表中看到1044端口。(参见图: 打开端口列表: netstat -a)。
打开端口的列表: netstat -a
Eclipse连接
在保证weblogic正在端口1044上监听正在来到的连接后,剩下的事就是要告诉Eclipse连接这个端口,你可以准备调试了。
1. 在Eclipse里,打开Run | Debug(参见图: 在Eclipse中创建远程Java应用配置)。
2. 在左边列中选择Remote Java Application,在列的底部点击New
3. 在Create configuration界面上,将被提示输入一些值。首先设置一个有意义的名词。在我的例子中设置为WebLogic Instance。对于项目,选择你想调试的包含源代码的Java工程。保留Connection Type为缺省值,等等Standard (Socket Attach)。对于Host,输入localhost。如果想调试远程服务器,输入主机名或者IP地址。对于端口,输入1044或者输入你定义在Weblogic启动脚本中的端口
4. 点击Apply
5. 确保Weblogic实例运行在调试模式。在界面上点击Debug。Eclipse应该自动进入Debug透视图,可以看到Debug试图下的堆栈跟踪。
6. 如果没有自动进入Debug透视图,选择Window | Open Perspective | Other然后点击Debug。
在Eclipse中创建远程Java应用配置
Eclipse调试器中的断点
Eclipse调试窗口应该自动在你第一个断点处自动弹出栈(参见图: Eclipse调试器中的断点)。然后,你可以使用调试器提供的所有功能,即变量值、进入代码,drop to frame等等。
参考
Debugging J2EE Applications
Connecting to a Remote VM with the Java Remote Application Launcher
Debugging with the Eclipse Platform
系统信息
Windows XP Professional
JDK 1.4.2_07
Eclipse 3.2
BEA WebLogic 8.1
JBoss 4.0.2
Tomcat 5.5.12