|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
你总不能说你写框架吧,那无疑会加大工作量,现在大多企业采取的是折中的办法,就是改别人写好的框架,可要改框架,前提是你对这个框架足够的了解,这就更难了。js 本文经由过程开辟一个JSP编纂器插件的示例,先容了Eclipse中设置JSP断点的办法,和怎样远程调试JSP。作为基本常识,本文的前两部分形貌了JAVADebug和JSR-45的基础道理。
情况请求:本文的代码是在Eclipse3.0.0,JDK1.4.2和Tomcat5.0.5上测试过的。
JAVA调试框架(JPDA)简介
JPDA是一个多层的调试框架,包含JVMDI、JDWP、JDI三个条理。JAVA假造机供应了JPDA的完成。其开辟工具作为调试客户端,能够便利的与假造机通信,举行调试。Eclipse恰是使用JPDA调试JAVA使用,现实上,一切JAVA开辟工具都是如许做的。SUNJDK还带了一个对照复杂的调试工具和示例。
- JVMDI界说了假造机必要完成的当地接口
- JDWP界说了JVM与调试客户端之间的通信协定
调试客户端和JVM既能够在统一台呆板上,也能够远程调试。JDK会包括一个默许的完成jdwp.dll,JVM同意天真的利用其他协定取代JDWP。SUNJDK有两种体例传输通信协定:Socket和共享内存(后者仅仅针对Windows),一样平常我们都接纳Socket体例。
你能够用上面的参数,以调试形式启动JVM
- -Xdebug-Xnoagent-Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n-XrunjdwpJVM加载jdwp.dlltransport=dt_socket利用Socket传输address暗示调试端标语server=y暗示JVM作为服务器,创建Socketsuspend=n暗示启动过程当中,JVM不会挂起往守候调试客户端毗连
复制代码 - JDI则是一组JAVA接口
假如是一个JAVA的调试客户端,只需完成JDI接口,使用JDWP协定,与假造机通信,就能够挪用JVMDI了。
下图为JPDA的基础架构:
- ComponentsDebuggerInterface/|-----------------------|/|VM|debuggee----(|-----------------------|<-------JVMDI-JavaVMDebugInterface|back-end||-----------------------|/|commchannel-(|<---------------JDWP-JavaDebugWireProtocol||---------------------||front-end||---------------------|<-------JDI-JavaDebugInterface|UI||---------------------|
复制代码 拜见:http://java.sun.com/j2se/1.4.2/docs/guide/jpda/architecture.html
Eclipse作为一个基于JAVA的调试客户端,使用org.eclipse.jdt.debugPlugin供应了JDI的详细完成。JDI接口次要包括上面4个包- com.sun.jdicom.sun.jdi.connectcom.sun.jdi.eventcom.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(DebuggingSupportforOtherLanguages)为那些非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的文件名和行号关照调试客户端。
我们用Tomcat5.0做个测试,有两个JSP,Hello.jsp和greeting.jsp,前者include后者。Tomcat会将他们编译成JAVA代码(Hello_jsp.java),JAVAClass(Hello_jsp.class)和JSP文件名/行号和JAVA行号之间的对应表(SMAP)。
Hello.jsp:
- 1<HTML>2<HEAD>3<TITLE>HelloExample</TITLE>4</HEAD>5<BODY>6<%@includefile="greeting.jsp"%>7</BODY>8</HTML>
复制代码 greeting.jsp:
1HelloThere!<P>2Goodbyeon<%=newjava.util.Date()%>
JSP编译后发生的Hello_jsp.java以下:
- Hello_jsp.java:1packageorg.apache.jsp;23importjavax.servlet.*;4importjavax.servlet.http.*;5importjavax.servlet.jsp.*;67publicfinalclassHello_jspextendsorg.apache.jasper.runtime.HttpJspBase8implementsorg.apache.jasper.runtime.JspSourceDependent{910privatestaticjava.util.Vector_jspx_dependants;1112static{13_jspx_dependants=newjava.util.Vector(1);14_jspx_dependants.add("/greeting.jsp");15}1617publicjava.util.ListgetDependants(){18return_jspx_dependants;19}2021publicvoid_jspService(HttpServletRequestrequest,HttpServletResponseresponse)22throwsjava.io.IOException,ServletException{2324JspFactory_jspxFactory=null;25PageContextpageContext=null;26HttpSessionsession=null;27ServletContextapplication=null;28ServletConfigconfig=null;29JspWriterout=null;30Objectpage=this;31JspWriter_jspx_out=null;323334try{35_jspxFactory=JspFactory.getDefaultFactory();36response.setContentType("text/html");37pageContext=_jspxFactory.getPageContext(this,request,response,38null,true,8192,true);39application=pageContext.getServletContext();40config=pageContext.getServletConfig();41session=pageContext.getSession();42out=pageContext.getOut();43_jspx_out=out;4445out.write("<HTML>
- ");46out.write("<HEAD>
- ");47out.write("<TITLE>HelloExample");48out.write("</TITLE>
- ");49out.write("</HEAD>
- ");50out.write("<BODY>
- ");51out.write("HelloThere!");52out.write("<P>
- Goodbyeon");53out.write(String.valueOf(newjava.util.Date()));54out.write("
- ");55out.write("
- ");56out.write("</BODY>
- ");57out.write("</HTML>
- ");58}catch(Throwablet){59if(!(tinstanceofjavax.servlet.jsp.SkipPageException)){60out=_jspx_out;61if(out!=null&&out.getBufferSize()!=0)62out.clearBuffer();63if(pageContext!=null)pageContext.handlePageException(t);64}65}finally{66if(_jspxFactory!=null)_jspxFactory.releasePageContext(pageContext);67}68}69}
复制代码 Tomcat又将这个JAVA代码编译为Hello_jsp.class,他们位于:$Tomcat_install_path$workStandalonelocalhost\_目次下。可是JSP文件名/行号和JAVA行号的对应表(以下简称SMAP)在那里呢?谜底是,它保留在Class中。假如用UltraEdit翻开这个Class文件,就能够找到SourceDebugExtension属性,这个属性用来保留SMAP。
JVM标准界说了ClassFile中能够包括SourceDebugExtension属性,保留SMAP:
- SourceDebugExtension_attribute{u2attribute_name_index;u4attribute_length;u1debug_extension[attribute_length];}
复制代码 我用javassist做了一个测试(javassist但是一个好东东,它能够静态改动Class的布局,JBOSS的AOP就使用了javassist,这里我们只利用它读取ClassFile的属性)
- publicstaticvoidmain(String[]args)throwsException{String[]files={ "E:Tomcat5_0_5workCatalinalocalhost\_orgapachejspHello_jsp.class",}; for(intk=0;k<files.length;k++){ Stringfile=files[k]; System.out.println("Class:"+file); ClassFileclassFile=newClassFile(newDataInputStream(newFileInputStream(file))); AttributeInfoattributeInfo=classFile.getAttribute("SourceDebugExtension"); System.out.println("attributename:"+attributeInfo.getName()+"]
- "); byte[]bytes=attributeInfo.get(); Stringstr=newString(bytes); System.out.println(str);}}
复制代码 这段代码显现了SourceDebugExtension属性,你能够看到SMAP的内容。编译JSP后,SMAP就被写进Class中,你也能够使用javassist修正ClassFile的属性。
上面就是Hello_jsp.class中保留的SMAP内容:
- SMAPE:Tomcat5_0_5workCatalinalocalhost\_orgapachejspHello_jsp.javaJSP*SJSP*F+0Hello.jsp/Hello.jsp+1greeting.jsp/greeting.jsp*L1:452:463:473:484:495:501#1:511:522:537#0:568: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详细的申明:
- 1:452:463:473:484:495:50(没有源文件代号,默许为Hello.jsp) 入手下手行号 停止行号Hello.jsp:1->Hello_jsp.java:452->463->47484->495->501#1:511:522:53(1#1暗示greeting.jsp的第1行)greeting.jsp:1->Hello_jsp.java:51522->537#0:568:57(7#0暗示Hello.jsp的第7行)Hello.jsp:7->Hello_jsp.java:568->57
复制代码 开辟一个JSP编纂器
Eclipse供应了TextEditor,作为文本编纂器的父类。因为Editor的开辟不是本文的重点,不做详细叙述。我们能够使用Eclipse的Plugin项目导游,天生一个复杂的JSP编纂器:
(1)点击File菜单,New->Project->Plug-inProject;
(2)输出项目称号JSP_DEBUG,下一步;
(3)输出pluginID:com.jsp.debug
PluginClassname:com.jsp.debug.JSP_DebugPlugin
(4)选择用模板创立
利用Plug-inwitheditor,输出
JavaPackageName:com.jsp.editors
EditorClassName:JSPEditor
Fileextension:jsp
一个jspeditor就发生了。
运转这个Plugin,新建一个JAVA项目,新建一个Hello.jsp和greeting.jsp,在Navigator视图双击jsp,这个editor就翻开了。
在JSP编纂器中设置断点
在编纂器中增加断点的操纵体例有两种,一种是在编纂器左边垂直标尺上双击,另外一种是在左边垂直标尺上点击鼠标右键,选择菜单"增加/删除断点"。
在Eclipse的完成中,增加断点实践上就是为IFile增加一个marker,范例是IBreakpoint.BREAKPOINT_MARKER,然后将断点注册到BreakpointManager。
BreakpointManager将发生一个BreakpointRequest,关照正在运转的JVMTarget,假如此时还没有启动JVM,会在JVM启动的时分,将一切断点一同关照JVMTarget。
增加断点利用一个AbstractRulerActionDelegate,重载createAction办法,前往一个IActionManageBreakpointRulerAction举措:
- publicclassManageBreakpointRulerActionDelegateextendsAbstractRulerActionDelegate{protectedIActioncreateAction(ITextEditoreditor,IVerticalRulerInforulerInfo){returnnewManageBreakpointRulerAction(rulerInfo,editor);}}
复制代码 为了将ManageBreakpointRulerActionDelegate增加到文本编纂器左边标尺的鼠标右键菜单,而且可以处置左边标尺的鼠标双击事务,在plugin.xml中到场界说。
处置双击事务:
- <extensionpoint="org.eclipse.ui.editorActions"> <editorContributiontargetID="com.jiaoly.editors.JSPEditor"id="com.jiaoly.debug.ManageBreakpointRulerActionDelegate"> <actionlabel="增加/删除断点"class="com.jiaoly.debug.ManageBreakpointRulerActionDelegate"actionID="RulerDoubleClick"id="com.jiaoly.debug.ManageBreakpointRulerActionDelegate"> </action> </editorContribution></extension>
复制代码 增加右键菜单:
- <extensionpoint="org.eclipse.ui.popupMenus"><viewerContributiontargetID="#TextRulerContext"id="com.jiaoly.debug.ManageBreakpointRulerActionDelegate"><actionlabel="增加/删除断点"class="com.jiaoly.debug.ManageBreakpointRulerActionDelegate"menubarPath="addition"id="com.jiaoly.debug.ManageBreakpointRulerActionDelegate"></action></viewerContribution></extension>
复制代码 ManageBreakpointRulerAction是实践增加断点的Action,完成了IUpdate接口,这个Action的事情,就是判别以后选中行是不是存在断点范例的Marker,假如不存在创立一个,假如存在,将它删除。
- publicclassManageBreakpointRulerActionextendsActionimplementsIUpdate{privateIVerticalRulerInforulerInfo;privateITextEditortextEditor;privateStringBPmarkerType;//当点Marker的范例privateListallMarkers;//以后鼠标点击行一切的MarkerprivateStringaddBP;//Action的显现称号publicManageBreakpointRulerAction(IVerticalRulerInforuler,ITextEditoreditor){this.rulerInfo=ruler;this.textEditor=editor;BPmarkerType=IBreakpoint.BREAKPOINT_MARKER;addBP="增加/删除断点";//$NON-NLS-1$setText(this.addBP);}publicvoidupdate(){this.allMarkers=this.fetchBPMarkerList();}publicvoidrun(){if(this.allMarkers.isEmpty())this.addMarker();elsethis.removeMarkers(this.allMarkers);}}
复制代码 update办法会在点击时起首挪用,这时候就能够搜集以后选中行是不是有marker了(挪用fetchBPMarkerList办法),假如有,就保留在变量allMarkers中。因为ManageBreakpointRulerAction每次都发生一个新的实例,因而不会发生抵触。
上面是update的挪用栈,能够看出,update办法是在鼠标点击事务中被挪用的:
- ManageBreakpointRulerAction.update()line:55ManageBreakpointRulerActionDelegate(AbstractRulerActionDelegate).update()line:114ManageBreakpointRulerActionDelegate(AbstractRulerActionDelegate).mouseDown(MouseEvent)line:139
复制代码 updae被挪用后,会实行run办法,就能够依据allMarkers.isEmpty()断定要删除仍是增加marker了。
增加断点的时分,起首使用IVerticalRulerInfo,猎取鼠标点击的行号,依据行号,从Document模子中获得该行的形貌IRegion,失掉入手下手字符地位和停止字符地位,创立一个JSP断点。
- protectedvoidaddMarker(){IEditorInputeditorInput=this.getTextEditor().getEditorInput();IDocumentdocument=this.getDocument();//thelinenumberofthelastmousebuttonactivityintrulerLine=this.getRulerInfo().getLineOfLastMouseButtonActivity();try{intlineNum=rulerLine+1;if(lineNum>0){//ReturnsadescriptionofthespecifiedlineIRegioniregion=document.getLineInformation(lineNum-1);intcharStart=iregion.getOffset();intcharEnd=(charStart+iregion.getLength())-1;JSPDebugUtility.createJspLineBreakpoint(this.getResource(),lineNum,charStart,charEnd);}}catch(CoreExceptioncoreexception){coreexception.printStackTrace();}catch(BadLocationExceptionbadlocationexception){badlocationexception.printStackTrace();}}
复制代码 注册JSP断点为撑持JSR-45标准,Eclipse中供应了JavaStratumLineBreakpoint。不外它今朝是一个internal的完成,在今后的版本中不克不及包管不作修正。这里为了复杂起见,间接从JavaStratumLineBreakpoint承继。
- publicclassJSPBreakpointextendsJavaStratumLineBreakpoint{publicJSPBreakpoint(IResourceresource,Stringstratum,StringsourceName,StringsourcePath,StringclassNamePattern,intlineNumber,intcharStart,intcharEnd,inthitCount,booleanregister,Mapattributes)throwsDebugException{super(resource,stratum,sourceName,sourcePath,classNamePattern,lineNumber,charStart,charEnd,hitCount,register,attributes);}}
复制代码 检察JavaStratumLineBreakpoint的源代码能够晓得,创立JavaStratumLineBreakpoint的时分做了两件事变:
(1)创立断点范例的marker,而且设置了marker的属性resource.createMarker(markerType);
(2)将断点注册到断点办理器
DebugPlugin.getDefault().getBreakpointManager().addBreakpoint(this);断点办理器卖力发生一个BreakpointRequest,关照正在运转的JVMTarget假如此时还没有启动JVM,会在JVM启动的时分,将一切断点一同关照JVMTarget。
上面是JavaStratumLineBreakpoint机关函数中的代码:
- IWorkspaceRunnablewr=newIWorkspaceRunnable(){publicvoidrun(IProgressMonitormonitor)throwsCoreException{//createthemarkersetMarker(resource.createMarker(markerType));//modifypatternStringpattern=classNamePattern;if(pattern!=null&&pattern.length()==0){pattern=null;}//addattributesaddLineBreakpointAttributes(attributes,getModelIdentifier(),true,lineNumber,charStart,charEnd);addStratumPatternAndHitCount(attributes,stratum,sourceName,sourcePath,pattern,hitCount);//setattributesensureMarker().setAttributes(attributes);register(register);}};run(null,wr);protectedvoidregister(booleanregister)throwsCoreException{if(register){DebugPlugin.getDefault().getBreakpointManager().addBreakpoint(this);}else{setRegistered(false);}}
复制代码 移除断点的时分,依据marker找到响应的IBreakpoint,从BreakpointManager中移除BreakpointManager会主动删除marker,关照JVMTarget。
- breakpointManager=DebugPlugin.getDefault().getBreakpointManager();IBreakpointbreakpoint=breakpointManager.getBreakpoint(IMarker);breakpointManager.removeBreakpoint(breakpoint,true);
复制代码 JSPBreakpoint重载了父类的addToTarget(JDIDebugTargettarget)办法。重载这个办法的目标是依据分歧的使用服务器,设置分歧的referenceTypeName和sourcePath。我们晓得,每种使用服务器编译JSP发生JavaClass称号的划定规矩都不不异,比方Tomcat编译Hello.jsp发生的Java类名为org.apache.jsp.Hello_jsp,而WebSphere6.0倒是com.ibm._jsp._Hello。只要断定服务器范例,才干晓得referenceTypeName和souecePath应当是甚么。今朝经由过程启动JVM时target称号来判别使用服务器范例:StringtargetString=target.getLaunch().getLaunchConfiguration().getName();假如targetString包括Tomcat,就以为是Tomcat。
发生referenceTypeName后起首创立一个ClassPrepareRequest关照,然后从vm中掏出一切的classes,假如是以后的Class,再创立一个增加断点关照。之以是如许做,是由于有大概这个Class还没有被JVM加载,间接关照JVM没有任何意义。在Class被加载的时分,JVM会关照Eclipse,这个时分,才发生增加断点关照。必要指出的是,本文示例代码猎取referenceTypeName的办法不是很完美:
(1)仅仅完成了Tomcat读者有乐趣能够完成更多的Web容器,比方JBoss3以上,WebSphere6.0
(2)一些特别情形没有处置比方路径名为package的jsp,路径名或文件名带无数字的jsp
- publicvoidaddToTarget(JDIDebugTargettarget)throwsCoreException{IMarkermarker=this.getMarker();IResourceresource=marker.getResource();StringtargetString=target.getLaunch().getLaunchConfiguration().getName();IJSPNameUtilutil=JSPDebugUtility.getJSPNameUtil(targetString);//pre-notificationfireAdding(target);StringreferenceTypeName;try{referenceTypeName=getPattern();//假如没有设置Pattern,依据Server的范例,发生新的Patternif(referenceTypeName==null||"".equals(referenceTypeName.trim())||"*".equals(referenceTypeName.trim())){referenceTypeName=util.referenceTypeName(resource);}}catch(CoreExceptione){JDIDebugPlugin.log(e);return;}this.ensureMarker().setAttribute(TYPE_NAME,referenceTypeName);StringsourcePath=util.sourcePath(resource);this.ensureMarker().setAttribute(JSPBreakpoint.SOURCE_PATH,sourcePath);StringclassPrepareTypeName=referenceTypeName;//假如这时候class还没有被加载,注册一个ClassPrepareRequest哀求////当class加载的时分,起首会触发JavaBreakpoint的handleClassPrepareEvent办法//挪用createRequest(target,event.referenceType())-->newRequest()-->//createLineBreakpointRequest()创立enable或disable断点的哀求////设置enable/disable举措在configureRequest()-->updateEnabledState(request)办法中//依据getMarker().getAttribute(ENABLED,false)断定断点是不是无效registerRequest(target.createClassPrepareRequest(classPrepareTypeName),target);//createbreakpointrequestsforeachclasscurrentlyloadedVirtualMachinevm=target.getVM();if(vm==null){target.requestFailed("Unable_to_add_breakpoint_-_VM_disconnected._1"),null);}Listclasses=null;try{classes=vm.allClasses();}catch(RuntimeExceptione){target.targetRequestFailed("JavaPatternBreakpoint.0"),e);}if(classes!=null){Iteratoriter=classes.iterator();while(iter.hasNext()){ReferenceTypetype=(ReferenceType)iter.next();if(installableReferenceType(type,target)){createRequest(target,type);}}}}
复制代码 调试JSP
如今我们能够调试JSP了。
(1)运转JSP_DEBUGplugin
起首在run->run中增加一个Run-timeWorkbench,点击run按钮,Eclipse的Plugin开辟情况会启动一个新的Eclipse,这个新启动的Eclipse中,我们创立的JSP_DEBUGplugin就能够利用了。新建一个JAVA项目Test(注重,必定如果JAVA项目),新建一个Hello.jsp和greeting.jsp,翻开Hello.jsp,在编纂器左边标尺双击,就呈现了一个断点。
(2)以Debug形式启动Tomcat:
windows入手下手->运转,键进cmd,启动一个命令行窗口:
cdE:Tomcat5_0_5in
(我的Tomcat安装在E:Tomcat5_0_5目次,JDK安装在D:j2sdk1.4.2)
- D:j2sdk1.4.2injava-Xdebug-Xnoagent-Xrunjdwp:transport=dt_socket,address=8888,server=y,
- suspend=n-Djava.endorsed.dirs="..commonendorsed"-classpath"D:j2sdk1.4.2lib ools.jar;..inootstrap.jar"-Dcatalina.base=".."-Dcatalina.home=".."-Djava.io.tmpdir=".. emp"org.apache.catalina.startup.Bootstrapstart
复制代码 -Xdebug-Xnoagent-Xrunjdwp:transport=dt_socket,address=8888,server=y,suspend=n暗示以调试体例启动,端标语是8888classpath中要到场D:j2sdk1.4.2lib ools.jar,由于我是Tomcat5.0.5,假如是5.5就不必要了。
(3)测试Hello.jsp
将Hello.jsp和greeting.jsp拷贝到E:Tomcat5_0_5webappsROOT目次,从扫瞄器会见Hello.jsphttp://localhost:8000/Hello.jsp。乐成的话就能够持续上面的事情了,假如失利,反省你的Tomcat设置。
(4)启动远程调试
在Eclipse中启动远程调试,将Eclipse作为一个Debug客户端,毗连到Tomcat。在Java透视图中,点击Run->Debug,增加一个RemoteJavaApplication,称号是StartTomcatServer(不克不及错,由于我们要依据这个称号,判别以后的WebServer范例)
project是创立的Test项目
Port为8888,和启动Tomcat时设置的一样
点击Debug按钮,就能够毗连到Tomcat上了。切换到Debug透视图,在Debug视图中,可以看到一切Tomcat中线程的列表。
(5)调试Hello.jsp
为Hello.jsp增加断点,然后从扫瞄器会见Hello.jsp,就能够在断点处挂起了。你可使用单步实行,也能够在Variables视图检察jsp中的变量信息。
因为Eclipse本身的完成,如今的JSPEditor有一个成绩,单步实行到includejsp行后,会从Hello.jsp的1行再次实行。这是由于EclipseJDTDebug视图缓存了StackFrame中已翻开的Editor,StackFrame不改动时,不会再从头盘算以后调试的是不是是其他Resource。原本应当翻开greeting.jsp的,如今却从Hello.jsp的第1行入手下手实行了。
停止语
良多集成开辟情况都撑持JSP的调试,在Eclipse中也有MyEclipse如许的插件完成相似的功效。可是在JSR-45标准发生前,每种使用服务器对JSPDebug的完成是纷歧样的,比方WebSphere5就是在JSP编译发生的JAVA代码中到场了两个数组,暗示源文件和行号的对应信息。Tomcat领先完成了JSR-45标准,WebSphere6.0如今也接纳这类形式,有乐趣的话,能够检察WebSphere6.0编译的Class,和Tomcat纷歧样,SMAP文件会和java代码同时发生。
可是启动server前,必要设置JVM参数was.debug.mode=true
同时在ibm-web-ext.xmi中设置
- <jspAttributesxmi:id="JSPAttribute_0"name="keepgenerated"value="true"/><jspAttributesxmi:id="JSPAttribute_1"name="createDebugClassfiles"value="true"/><jspAttributesxmi:id="JSPAttribute_2"name="debugEnabled"value="true"/>
复制代码 使用本文的基础道理,我们也能够开辟其他基于JAVA剧本言语的编纂器(比方Groovy),为这个编译器到场Debug的功效。
JAVA是一种可以撰写跨平台应用软件的面向对象的程序设计语言,由升阳(SunMicrosystems)公司的詹姆斯·高斯林(JamesGosling)等人于1990年代初开发。 |
|