进入旧版 | 服务项目 | 成功案例 | 联系方式 | 过客留言 | 友情链接
   
设为首页
加入收藏
联系我们
网站首页 | 新闻资讯 | 操作系统 | 办公软件 | 网络软件 | 工具软件 | 媒体动画 | 网页制作 | 网站开发 | 程序开发 | 平面设计
Photoshop视频教程 | Word入门 | Flash入门 | JScript | VBScript | ASP | PHP | ADO | 网页特效 | 3DS MAX6.0命令 | 系统进程
您当前的位置:GOODSGY电脑学习网 -> 网站开发 -> JSP -> 文章内容  
开发一个调试JSP的Eclipse插件

本文通过开发一个JSP 编辑器插件的示例,介绍了 Eclipse 中设置 JSP 断点的方法,以及如何远程调试 JSP。作为基础知识,本文的前两部分描述了 JAVA Debug 和 JSR-45 的基本原理。

  环境要求: 本文的代码是在 Eclipse3.0.0,JDK1.4.2 和 Tomcat5.0.5 上测试过的。

  JAVA 调试框架(JPDA)简介

  JPDA 是一个多层的调试框架,包括 JVMDI、JDWP、JDI 三个层次。JAVA 虚拟机提供了 JPDA 的实现。其开发工具作为调试客户端,可以方便的与虚拟机通讯,进行调试。Eclipse 正是利用 JPDA 调试 JAVA 应用,事实上,所有 JAVA 开发工具都是这样做的。SUN JDK 还带了一个比较简单的调试工具以及示例。
  • JVMDI 定义了虚拟机需要实现的本地接口
  • JDWP 定义了JVM与调试客户端之间的通讯协议

    调试客户端和JVM 既可以在同一台机器上,也可以远程调试。JDK 会包含一个默认的实现 jdwp.dll,JVM 允许灵活的使用其他协议代替 JDWP。SUN JDK 有两种方式传输通讯协议:Socket 和共享内存(后者仅仅针对 Windows),一般我们都采用 Socket 方式。

    你可以用下面的参数,以调试模式启动JVM

    -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n -Xrunjdwp JVM 加载 jdwp.dll transport=dt_socket 使用 Socket 传输 address 表示调试端口号 server=y 表示 JVM 作为服务器,建立 Socket suspend=n 表示启动过程中,JVM 不会挂起去等待调试客户端连接

  • JDI 则是一组JAVA接口

    如果是一个 JAVA 的调试客户端,只要实现 JDI 接口,利用JDWP协议,与虚拟机通讯,就可以调用JVMDI了。
  下图为 JPDA 的基本架构:

Components Debugger Interface / |-----------------------| / | VM | debuggee ----( |-----------------------| <------- JVMDI - Java VM Debug Interface \ | back-end | \ |-----------------------| / | comm channel -( | <--------------- JDWP - Java Debug Wire Protocol \ | |---------------------| | front-end | |---------------------| <------- JDI - Java Debug Interface | UI | |---------------------| 

  参见:http://java.sun.com/j2se/1.4.2/docs/guide/jpda/architecture.HTML

  Eclipse作为一个基于 JAVA 的调试客户端,利用 org.eclipse.jdt.debug Plugin 提供了JDI 的具体实现。JDI 接口主要包含下面 4 个包
com.sun.jdi com.sun.jdi.connect com.sun.jdi.event com.sun.jdi.request 
  本文不对 JDI 进行深入阐述,这里重点介绍 JDI 中与断点相关的接口。
  • com.sun.jdi

    主要是JVM(VirtualMachine) 线程(ThreadReference) 调用栈(StackFrame) 以及类型、实例的描述。利用这组接口,调试客户端可以用类似类反射的方式,得到所有类型的定义,动态调用 Class 的方法。
  • com.sun.jdi.event

    封装了JVM 产生的事件, JVM 正是将这些事件通知给调试客户端的。例如 BreakpointEvent 就是 JVM 执行到断点的时候,发出的事件;ClassPrepareEvent就是 Class 被加载时发出的事件。

  • com.sun.jdi.request

    封装了调试客户端可以向 JVM发起的请求。例如 BreakpointRequest 向 JVM 发起一个添加断点的请求;ClassPrepareRequest 向 JVM 注册一个类加载请求,JVM 在加载指定 Class 的时候,就会发出一个 ClassPrepareEvent 事件。

  JSR-45规范

  JSR-45(Debugging Support for Other Languages)为那些非 JAVA 语言写成,却需要编译成 JAVA 代码,运行在 JVM 中的程序,提供了一个进行调试的标准机制。也许字面的意思有点不好理解,什么算是非 JAVA 语言呢?其实 JSP 就是一个再好不过的例子,JSR-45 的样例就是一个 JSP。

  JSP的调试一直依赖于具体应用服务器的实现,没有一个统一的模式,JSR-45 针对这种情况,提供了一个标准的模式。我们知道,JAVA 的调试中,主要根据行号作为标志,进行定位。但是 JSP 被编译为 JAVA 代码之后,JAVA 行号与 JSP 行号无法一一对应,怎样解决呢?

  JSR-45 是这样规定的:JSP 被编译成 JAVA 代码时,同时生成一份 JSP 文件名和行号与 JAVA 行号之间的对应表(SMAP)。JVM 在接受到调试客户端请求后,可以根据这个对应表(SMAP),从 JSP 的行号转换到 JAVA 代码的行号;JVM 发出事件通知前, 也根据对应表(SMAP)进行转化,直接将 JSP 的文件名和行号通知调试客户端。

  我们用 Tomcat 5.0 做个测试,有两个 JSP,Hello.JSP 和 greeting.JSP,前者 include 后者。Tomcat会将他们编译成 JAVA 代码(Hello_JSP.java),JAVA Class(Hello_JSP.class) 以及 JSP 文件名/行号和 JAVA 行号之间的对应表(SMAP)。

  Hello.JSP: www.goodsgy.com

1 2 3 4 5 6 <%@ include file="greeting.jsp" %>7 8www.goodsgy.com

greeting.JSP:

1 Hello There! www.goodsgy.com

2 Goodbye on <%= new java.util.Date() %>

  JSP 编译后产生的Hello_JSP.java 如下:

Hello_JSP.java: 1 package org.apache.JSP; 2 3 import javax.servlet.*; 4 import javax.servlet.http.*; 5 import javax.servlet.JSP.*; 6 7 public final class Hello_JSP extends org.apache.jASPer.runtime.HttpJSPBase 8 implements org.apache.jASPer.runtime.JSPSourceDependent { 9 10 private static java.util.Vector _JSPx_dependants; 11 12 static { 13 _JSPx_dependants = new java.util.Vector(1); 14 _JSPx_dependants.add("/greeting.JSP"); 15 } 16 17 public java.util.List getDependants() { 18 return _JSPx_dependants; 19 } 20 21 public void _JSPService(HttpServletRequest request, HttpServletResponse response) 22 throws java.io.IOException, ServletException { 23 24 JSPFactory _JSPxFactory = null; 25 PageContext pageContext = null; 26 HttpSession session = null; 27 ServletContext application = null; 28 ServletConfig config = null; 29 JSPWriter out = null; 30 Object page = this; 31 JSPWriter _JSPx_out = null; 32 33 34 try { 35 _JSPxFactory = JSPFactory.getDefaultFactory(); 36 response.setContentType("text/HTML"); 37 pageContext = _JSPxFactory.getPageContext(this, request, response, 38 null, true, 8192, true); 39 application = pageContext.getServletContext(); 40 config = pageContext.getServletConfig(); 41 session = pageContext.getSession(); 42 out = pageContext.getOut(); 43 _JSPx_out = out; 44 45 out.write("\r\n"); 46 out.write("\r\n"); 47 out.write("\r\n"); 49 out.write("\r\n"); 50 out.write("\r\n"); 51 out.write("Hello There!"); 52 out.write("

\r\nGoodbye on "); 53 out.write(String.valueOf( new java.util.Date() )); 54 out.write(" \r\n"); 55 out.write(" \r\n"); 56 out.write("\r\n"); 57 out.write("\r\n"); 58 } catch (Throwable t) { 59 if (!(t instanceof javax.servlet.JSP.SkipPageException)){ 60 out = _JSPx_out; 61 if (out != null && out.getBufferSize() != 0) 62 out.clearBuffer(); 63 if (pageContext != null) pageContext.handlePageException(t); 64 } 65 } finally { 66 if (_JSPxFactory != null) _JSPxFactory.releasePageContext ( pageContext); 67 } 68 } 69 }www.goodsgy.com


  Tomcat 又将这个 JAVA 代码编译为 Hello_JSP.class,他们位于: $Tomcat_install_path$\work\Standalone\localhost\_ 目录下。但是 JSP 文件名/行号和 JAVA 行号的对应表(以下简称SMAP) 在哪里呢?答案是,它保存在 Class 中。如果用 UltraEdit 打开这个 Class 文件,就可以找到 SourceDebugExtension 属性,这个属性用来保存 SMAP。

  JVM 规范定义了 ClassFile 中可以包含 SourceDebugExtension 属性,保存 SMAP:

www.goodsgy.com

SourceDebugExtension_attribute { u2 attribute_name_index; u4 attribute_length; u1 debug_extension[attribute_length]; } 


  我用 javassist 做了一个测试(javassist可是一个好东东,它可以动态改变Class的结构,JBOSS 的 AOP就利用了javassist,这里我们只使用它读取ClassFile的属性)

www.goodsgy.com

public static void main(String[] args) throws Exception{ String[]files = {    "E:\\Tomcat5_0_5\\work\\Catalina\\localhost\\_\\org\\apache\\JSP\\Hello_JSP.class", };  for(int k = 0; k < files.length; k++){   String file = files[k];   System.out.println("Class : " + file);   ClassFile classFile = new ClassFile(new DataInputStream(new FileInputStream(file)));     AttributeInfo attributeInfo = classFile.getAttribute("SourceDebugExtension");   System.out.println("attribute name :" + attributeInfo.getName() + "]\n\n");   byte[]bytes = attributeInfo.get();   String str = new String(bytes);   System.out.println(str); } } 


  这段代码显示了SourceDebugExtension 属性,你可以看到SMAP 的内容。编译JSP后,SMAP 就被写入 Class 中, 你也可以利用 javassist 修改 ClassFile 的属性。

  下面就是 Hello_JSP.class 中保存的 SMAP 内容:

www.goodsgy.com

SMAP E:\Tomcat5_0_5\work\Catalina\localhost\_\org\apache\JSP\Hello_JSP.java JSP *S JSP *F + 0 Hello.JSP /Hello.JSP + 1 greeting.JSP /greeting.JSP *L 1:45 2:46 3:47 3:48 4:49 5:50 1#1:51 1:52 2:53 7#0:56 8:57 *E


  首先注明JAVA代码的名称:Hello_JSP.java,然后是 stratum 名称: JSP。随后是两个JSP文件的名称 :Hello.JSP、greeting.JSP。两个JSP文件共10行,产生的Hello_JSP共69行代码。最后也是最重要的内容就是源文件文件名/行号和目标文件行号的对应关系(*L 与 *E之间的部分)

  在规范定义了这样的格式:

  源文件行号 # 源文件代号,重复次数 : 目标文件开始行号,目标文件行号每次增加的数量
(InputStartLine # LineFileID , RepeatCount : OutputStartLine , OutputLineIncrement)

  源文件行号(InputStartLine) 目标文件开始行号(OutputStartLine) 是必须的。下面是对这个SMAP具体的说明:

www.goodsgy.com

1:45 2:46 3:47 3:48 4:49 5:50(没有源文件代号,默认为Hello.JSP)                    开始行号   结束行号 Hello.JSP: 1 ->Hello_JSP.java: 45 2 ->46 3 ->47 48 4 ->49 5 ->50 1#1:51 1:52 2:53(1#1表示 greeting.JSP 的第1行) greeting.JSP: 1 ->Hello_JSP.java: 51 52 2 ->53 7#0:56 8:57(7#0表示 Hello.JSP 的第7行) Hello.JSP: 7 ->Hello_JSP.java: 56 8 ->57 
本文通过开发一个JSP 编辑器插件的示例,介绍了 Eclipse 中设置 JSP 断点的方法,以及如何远程调试 JSP。作为基础知识,本文的前两部分描述了 JAVA Debug 和 JSR-45 的基本原理。 

  环境要求: 本文的代码是在 Eclipse3.0.0,JDK1.4.2 和 Tomcat5.0.5 上测试过的。

  JAVA 调试框架(JPDA)简介

  JPDA 是一个多层的调试框架,包括 JVMDI、JDWP、JDI 三个层次。JAVA 虚拟机提供了 JPDA 的实现。其开发工具作为调试客户端,可以方便的与虚拟机通讯,进行调试。Eclipse 正是利用 JPDA 调试 JAVA 应用,事实上,所有 JAVA 开发工具都是这样做的。SUN JDK 还带了一个比较简单的调试工具以及示例。
  • JVMDI 定义了虚拟机需要实现的本地接口
  • JDWP 定义了JVM与调试客户端之间的通讯协议

    调试客户端和JVM 既可以在同一台机器上,也可以远程调试。JDK 会包含一个默认的实现 jdwp.dll,JVM 允许灵活的使用其他协议代替 JDWP。SUN JDK 有两种方式传输通讯协议:Socket 和共享内存(后者仅仅针对 Windows),一般我们都采用 Socket 方式。

    你可以用下面的参数,以调试模式启动JVM

    -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n -Xrunjdwp JVM 加载 jdwp.dll transport=dt_socket 使用 Socket 传输 address 表示调试端口号 server=y 表示 JVM 作为服务器,建立 Socket suspend=n 表示启动过程中,JVM 不会挂起去等待调试客户端连接

  • JDI 则是一组JAVA接口

    如果是一个 JAVA 的调试客户端,只要实现 JDI 接口,利用JDWP协议,与虚拟机通讯,就可以调用JVMDI了。
  下图为 JPDA 的基本架构:

Components Debugger Interface / |-----------------------| / | VM | debuggee ----( |-----------------------| <------- JVMDI - Java VM Debug Interface \ | back-end | \ |-----------------------| / | comm channel -( | <--------------- JDWP - Java Debug Wire Protocol \ | |---------------------| | front-end | |---------------------| <------- JDI - Java Debug Interface | UI | |---------------------| 

  参见:http://java.sun.com/j2se/1.4.2/docs/guide/jpda/architecture.HTML

  Eclipse作为一个基于 JAVA 的调试客户端,利用 org.eclipse.jdt.debug Plugin 提供了JDI 的具体实现。JDI 接口主要包含下面 4 个包
com.sun.jdi com.sun.jdi.connect com.sun.jdi.event com.sun.jdi.request 
  本文不对 JDI 进行深入阐述,这里重点介绍 JDI 中与断点相关的接口。
  • com.sun.jdi

    主要是JVM(VirtualMachine) 线程(ThreadReference) 调用栈(StackFrame) 以及类型、实例的描述。利用这组接口,调试客户端可以用类似类反射的方式,得到所有类型的定义,动态调用 Class 的方法。
  • com.sun.jdi.event

    封装了JVM 产生的事件, JVM 正是将这些事件通知给调试客户端的。例如 BreakpointEvent 就是 JVM 执行到断点的时候,发出的事件;ClassPrepareEvent就是 Class 被加载时发出的事件。

  • com.sun.jdi.request

    封装了调试客户端可以向 JVM发起的请求。例如 BreakpointRequest 向 JVM 发起一个添加断点的请求;ClassPrepareRequest 向 JVM 注册一个类加载请求,JVM 在加载指定 Class 的时候,就会发出一个 ClassPrepareEvent 事件。
  JSR-45规范

  JSR-45(Debugging Support for Other Languages)为那些非 JAVA 语言写成,却需要编译成 JAVA 代码,运行在 JVM 中的程序,提供了一个进行调试的标准机制。也许字面的意思有点不好理解,什么算是非 JAVA 语言呢?其实 JSP 就是一个再好不过的例子,JSR-45 的样例就是一个 JSP。

  JSP的调试一直依赖于具体应用服务器的实现,没有一个统一的模式,JSR-45 针对这种情况,提供了一个标准的模式。我们知道,JAVA 的调试中,主要根据行号作为标志,进行定位。但是 JSP 被编译为 JAVA 代码之后,JAVA 行号与 JSP 行号无法一一对应,怎样解决呢?

  JSR-45 是这样规定的:JSP 被编译成 JAVA 代码时,同时生成一份 JSP 文件名和行号与 JAVA 行号之间的对应表(SMAP)。JVM 在接受到调试客户端请求后,可以根据这个对应表(SMAP),从 JSP 的行号转换到 JAVA 代码的行号;JVM 发出事件通知前, 也根据对应表(SMAP)进行转化,直接将 JSP 的文件名和行号通知调试客户端。

  我们用 Tomcat 5.0 做个测试,有两个 JSP,Hello.JSP 和 greeting.JSP,前者 include 后者。Tomcat会将他们编译成 JAVA 代码(Hello_JSP.java),JAVA Class(Hello_JSP.class) 以及 JSP 文件名/行号和 JAVA 行号之间的对应表(SMAP)。

  Hello.JSP:

1 2 3 4 5 6 <%@ include file="greeting.jsp" %>7 8 

  greeting.JSP:

1 Hello There!

2 Goodbye on <%= new java.util.Date() %>

  JSP 编译后产生的Hello_JSP.java 如下:

Hello_JSP.java: 1 package org.apache.JSP; 2 3 import javax.servlet.*; 4 import javax.servlet.http.*; 5 import javax.servlet.JSP.*; 6 7 public final class Hello_JSP extends org.apache.jASPer.runtime.HttpJSPBase 8 implements org.apache.jASPer.runtime.JSPSourceDependent { 9 10 private static java.util.Vector _JSPx_dependants; 11 12 static { 13 _JSPx_dependants = new java.util.Vector(1); 14 _JSPx_dependants.add("/greeting.JSP"); 15 } 16 17 public java.util.List getDependants() { 18 return _JSPx_dependants; 19 } 20 21 public void _JSPService(HttpServletRequest request, HttpServletResponse response) 22 throws java.io.IOException, ServletException { 23 24 JSPFactory _JSPxFactory = null; 25 PageContext pageContext = null; 26 HttpSession session = null; 27 ServletContext application = null; 28 ServletConfig config = null; 29 JSPWriter out = null; 30 Object page = this; 31 JSPWriter _JSPx_out = null; 32 33 34 try { 35 _JSPxFactory = JSPFactory.getDefaultFactory(); 36 response.setContentType("text/HTML"); 37 pageContext = _JSPxFactory.getPageContext(this, request, response, 38 null, true, 8192, true); 39 application = pageContext.getServletContext(); 40 config = pageContext.getServletConfig(); 41 session = pageContext.getSession(); 42 out = pageContext.getOut(); 43 _JSPx_out = out; 44 45 out.write("\r\n"); 46 out.write("\r\n"); 47 out.write("\r\n"); 49 out.write("\r\n"); 50 out.write("\r\n"); 51 out.write("Hello There!"); 52 out.write("

\r\nGoodbye on "); 53 out.write(String.valueOf( new java.util.Date() )); 54 out.write(" \r\n"); 55 out.write(" \r\n"); 56 out.write("\r\n"); 57 out.write("\r\n"); 58 } catch (Throwable t) { 59 if (!(t instanceof javax.servlet.JSP.SkipPageException)){ 60 out = _JSPx_out; 61 if (out != null && out.getBufferSize() != 0) 62 out.clearBuffer(); 63 if (pageContext != null) pageContext.handlePageException(t); 64 } 65 } finally { 66 if (_JSPxFactory != null) _JSPxFactory.releasePageContext ( pageContext); 67 } 68 } 69 }www.goodsgy.com

Tomcat 又将这个 JAVA 代码编译为 Hello_JSP.class,他们位于: $Tomcat_install_path$\work\Standalone\localhost\_ 目录下。但是 JSP 文件名/行号和 JAVA 行号的对应表(以下简称SMAP) 在哪里呢?答案是,它保存在 Class 中。如果用 UltraEdit 打开这个 Class 文件,就可以找到 SourceDebugExtension 属性,这个属性用来保存 SMAP。

  JVM 规范定义了 ClassFile 中可以包含 SourceDebugExtension 属性,保存 SMAP:

www.goodsgy.com

SourceDebugExtension_attribute { u2 attribute_name_index; u4 attribute_length; u1 debug_extension[attribute_length]; } 


  我用 javassist 做了一个测试(javassist可是一个好东东,它可以动态改变Class的结构,JBOSS 的 AOP就利用了javassist,这里我们只使用它读取ClassFile的属性)

www.goodsgy.com

public static void main(String[] args) throws Exception{ String[]files = {    "E:\\Tomcat5_0_5\\work\\Catalina\\localhost\\_\\org\\apache\\JSP\\Hello_JSP.class", };  for(int k = 0; k < files.length; k++){   String file = files[k];   System.out.println("Class : " + file);   ClassFile classFile = new ClassFile(new DataInputStream(new FileInputStream(file)));     AttributeInfo attributeInfo = classFile.getAttribute("SourceDebugExtension");   System.out.println("attribute name :" + attributeInfo.getName() + "]\n\n");   byte[]bytes = attributeInfo.get();   String str = new String(bytes);   System.out.println(str); } } 


  这段代码显示了SourceDebugExtension 属性,你可以看到SMAP 的内容。编译JSP后,SMAP 就被写入 Class 中, 你也可以利用 javassist 修改 ClassFile 的属性。

  下面就是 Hello_JSP.class 中保存的 SMAP 内容:

www.goodsgy.com

SMAP E:\Tomcat5_0_5\work\Catalina\localhost\_\org\apache\JSP\Hello_JSP.java JSP *S JSP *F + 0 Hello.JSP /Hello.JSP + 1 greeting.JSP /greeting.JSP *L 1:45 2:46 3:47 3:48 4:49 5:50 1#1:51 1:52 2:53 7#0:56 8:57 *E


  首先注明JAVA代码的名称:Hello_JSP.java,然后是 stratum 名称: JSP。随后是两个JSP文件的名称 :Hello.JSP、greeting.JSP。两个JSP文件共10行,产生的Hello_JSP共69行代码。最后也是最重要的内容就是源文件文件名/行号和目标文件行号的对应关系(*L 与 *E之间的部分)

  在规范定义了这样的格式:

  源文件行号 # 源文件代号,重复次数 : 目标文件开始行号,目标文件行号每次增加的数量
(InputStartLine # LineFileID , RepeatCount : OutputStartLine , OutputLineIncrement)

  源文件行号(InputStartLine) 目标文件开始行号(OutputStartLine) 是必须的。下面是对这个SMAP具体的说明:

www.goodsgy.com

1:45 2:46 3:47 3:48 4:49 5:50(没有源文件代号,默认为Hello.JSP)                    开始行号   结束行号 Hello.JSP: 1 ->Hello_JSP.java: 45 2 ->46 3 ->47 48 4 ->49 5 ->50 1#1:51 1:52 2:53(1#1表示 greeting.JSP 的第1行) greeting.JSP: 1 ->Hello_JSP.java: 51 52 2 ->53 7#0:56 8:57(7#0表示 Hello.JSP 的第7行) Hello.JSP: 7 ->Hello_JSP.java: 56 8 ->57
调试JSP

  现在我们可以调试 JSP 了。

  (1)运行 JSP_DEBUG plugin

  首先在 run ->run 中添加一个 Run-time Workbench,点击 run 按钮,Eclipse 的Plugin开发环境会启动一个新的Eclipse,这个新启动的 Eclipse 中,我们创建的 JSP_DEBUG plugin 就可以使用了。新建 一个 JAVA 项目 Test (注意,一定要是JAVA项目),新建一个 Hello.JSP 和 greeting.JSP,打开Hello.JSP,在编辑器左侧标尺双击,就出现了一个断点。

  (2)以 Debug 模式启动Tomcat:

  windows 开始 ->运行,键入 cmd,启动一个命令行窗口:

  cd E:\Tomcat5_0_5\bin

  (我的 Tomcat 安装在 E:\Tomcat5_0_5 目录,JDK 安装在 D:\j2sdk1.4.2)

D:\j2sdk1.4.2\bin\java -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=8888,server=y,
suspend=n -Djava.endorsed.dirs="..\common\endorsed" -classpath "D:\j2sdk1.4.2\lib\tools.jar;..\bin\bootstrap.jar" -Dcatalina.base=".." -Dcatalina.home=".." -Djava.io.tmpdir="..\temp" org.apache.catalina.startup.Bootstrap start


  -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=8888,server=y,suspend=n 表示以调试方式启动,端口号是 8888 classpath中要加入 D:\j2sdk1.4.2\lib\tools.jar,因为我是 Tomcat5.0.5,如果是5.5就不需要了。

  (3) 测试Hello.JSP

  将 Hello.JSP 和 greeting.JSP 拷贝到 E:\Tomcat5_0_5\webapps\ROOT 目录,从浏览器访问 Hello.JSP http://localhost:8000/Hello.JSP。成功的话就可以继续下面的工作了,如果失败,检查你的Tomcat设置。

  (4)启动远程调试

  在 Eclipse 中启动远程调试,将 Eclipse 作为一个 Debug 客户端,连接到 Tomcat 。在 Java 透视图中,点击 Run ->Debug ,添加一个 Remote Java Application,名称是 Start Tomcat Server(不能错,因为我们要根据这个名称,判断当前的 Web Server 类型)

  project是创建的 Test 项目

  Port 为 8888,和启动 Tomcat 时设置的一样www.goodsgy.com

www.goodsgy.com

  点击 Debug 按钮,就可以连接到 Tomcat 上了。切换到 Debug 透视图,在Debug 视图中,能够看到所有 Tomcat 中线程的列表。

  (5)调试Hello.JSP

  为 Hello.JSP 添加断点,然后从浏览器访问Hello.JSP,就可以在断点处挂起了。你可以使用单步执行,也可以在Variables视图查看JSP中的变量信息。

  由于 Eclipse 自身的实现,现在的 JSP Editor 有一个问题,单步执行到 include JSP 行后,会从Hello.JSP的1行再次执行。这是因为 Eclipse JDT Debug视图缓存了 StackFrame 中已经打开的Editor,StackFrame不改变时,不会再重新计算当前调试的是否是其他Resource。本来应该打开 greeting.JSP的,现在却从 Hello.JSP 的第 1 行开始执行了。

  结束语

  很多集成开发环境都支持 JSP 的调试,在 Eclipse 中也有 MyEclipse 这样的插件完成类似的功能。但是在 JSR-45 规范产生前,每种应用服务器对 JSP Debug 的实现是不一样的,例如 WebSphere 5 就是在 JSP 编译产生的 JAVA 代码中加入了两个数组,表示源文件和行号的对应信息。Tomcat 率先实现了 JSR-45 规范,WebSphere 6.0 现在也采取这种模式, 有兴趣的话,可以查看 WebSphere 6.0 编译的 Class,和 Tomcat 不一样,SMAP 文件会和java代码同时产生。

  但是启动server前,需要设置 JVM 参数 was.debug.mode = true

  同时在 ibm-web-ext.xmi 中设置

www.goodsgy.com


  利用本文的基本原理,我们也可以开发其他基于 JAVA 脚本语言的编辑器(例如 Groovy),为这个编译器加入 Debug 的功能。

在百度中搜索:开发一个调试JSP的Eclipse插件
在Google中搜索:开发一个调试JSP的Eclipse插件
在Yahoo中搜索:开发一个调试JSP的Eclipse插件

收藏到网摘:新浪VIVI 365key 我摘 POCO网摘 博采中心 YouNote 和讯网摘 天天收藏
[] [返回上一页] [打 印] [收 藏]
上一篇文章:将Word表格一分为二

 相关文章    最新文章
· Novell:Linux消费市场开发仍需3-5年时间..
· 微软:IE8仍将兼容为IE7开发的页面
· 微软称IE 8将推动网页开发人员技术创新
· Hibernate+Struts的J2EE应用开发
· 基于Hibernate和Struts的J2EE应用开发
· 微软下一代系统Windows 7将在印度开发
· [组图] Flash CS3 组件开发教程
· [图文] 如何用 JavaHelp 系统开发和交付更..
· [图文] 创建自定义代码片段 提高CSS布局开..
· AJAX将成为移动Web2.0时代首选开发平台
 
· 提升JSP页面响应速度的七大秘籍绝招
· 开发一个调试JSP的Eclipse插件
· JSP报表打印的一种简单解决方案
· JSP/Servlet的重定向技术综述
· java的md5加密类(zt)
· 一个用来访问http服务器的东西。功能类似..
· 菜鸟调试手记一(sql server 中文问题)
· Java性能优化技巧集锦(2)
· 用java压缩文件示例(没有中文问题)
· 使用XML/HTC/DHTML模拟标准Windows菜单

∷相关文章评论∷    (评论内容只代表网友观点,与本站立场无关!) [更多评论…]
站内搜索

精彩图文
  网站导航  
操作系统 办公软件 网络软件
Vista Windows2003 WindowsXP Windows2000/NT Windows9X/ME Linux 其他 Word Excel Powerpoint Outlook 金山系列 其他 网页浏览 上传下载 联络聊天 邮件工具 服务器软件 网络辅助
工具软件 媒体动画 网页制作
系统工具 媒体工具 压缩工具 图文处理 文件管理 其他 3DMAX Authorware Director Maya 视频处理 其他 Flash Dreamweaver FireWorks FrontPage LiveMotion Golive HTML/CSS 其它
网站开发 平面设计 程序设计
ASP JSP PHP CGI JavaScript VBScript XML/SOAP Web服务器 Photoshop PhotoImpact CorelDraw Illustrator Freehand 设计欣赏 其他 VB VC .NET C/C++ DELPHI JAVA

冀ICP备05019428号
Copyright © 2004-2008 电脑学习网 Inc.All rights reserved.
TEL:13832340607
QQ:39873155
E_Mail:goodsgy(#)hotmail.com   (把(#)替换成@)
MSN:goodsgy(#)hotmail.com   (把(#)替换成@)