Develop an Eclipse plug-in for debugging JSP __jsp

Source: Internet
Author: User
Tags tomcat server websphere application server

June 01, 2005 This article describes how to set up a JSP breakpoint in Eclipse and how to debug a JSP remotely by developing an example of a JSP editor plug-in. As a basic knowledge, the first two parts of this article describe the fundamentals of JAVA Debug and JSR-45.

Environmental requirements: The code in this article was tested on eclipse3.0.0,jdk1.4.2 and Tomcat5.0.5.

Introduction to the JAVA Debugging framework (JPDA)

JPDA is a multi-layer debugging framework that includes three levels of Jvmdi, JDWP, and JDI. The JAVA virtual machine provides a JPDA implementation. As the debugging client, the development tools can be conveniently communicated with the virtual machine and debugged. Eclipse is using JPDA to debug Java applications, and in fact all Java development tools do this. The SUN JDK also brings a simpler debugging tool and example. JVMDI defines the local interface that a virtual machine needs to implement JDWP defines the communication protocol between the JVM and the debugging client.

Debugging clients and JVMs can be either on the same machine or remotely. The JDK will contain a default implementation JDWP.DLL,JVM allow flexible use of other protocols instead of JDWP. The SUN JDK has two ways of communicating protocols: Sockets and Shared memory (which is only for Windows), and we generally use sockets.

You can use the following parameters to start the JVM in debug mode


JDI is a set of Java interfaces

If it is a JAVA debugging client, as long as the implementation of the JDI interface, using the JDWP protocol, with the virtual machine communication, you can call the Jvmdi.

The following figure is the basic schema for JPDA:


See also: http://java.sun.com/j2se/1.4.2/docs/guide/jpda/architecture.html

As a JAVA-based debugging client, Eclipse provides a concrete implementation of JDI using Org.eclipse.jdt.debug Plugin. The JDI interface consists mainly of the following 4 packages

Com.sun.jdi 
        com.sun.jdi.connect 
        com.sun.jdi.event 
        

This article does not carry on the elaboration to the JDI, here emphatically introduces the breakpoint related interface in the JDI Com.sun.jdi
It is mainly the JVM (virtualmachine) thread (threadreference) call stack (stackframe) and the description of the type, instance. With this set of interfaces, debugging clients can get all types of definitions and dynamically invoke class methods in a way that is similar to class reflection. Com.sun.jdi.event
Encapsulates the events generated by the JVM, which is what the JVM notifies the debugging client. For example Breakpointevent is the event that the JVM emits when it executes to a breakpoint; Classprepareevent is the event that Class is emitted when it is loaded. Com.sun.jdi.request
Encapsulates a request that the debug client can initiate to the JVM. For example, Breakpointrequest initiates a request to add a breakpoint to the JVM; classpreparerequest registers a class load request to the JVM, and the JVM emits a classprepareevent event when it loads the specified class 。




Back to the top of the page


JSR-45 specification

JSR-45 (Debugging Support for the other Languages) is a standard mechanism for debugging, written for those not in the Java language, and that needs to be compiled into JAVA code and run in a JVM. Maybe the literal meaning is a bit hard to understand and what is not a JAVA language. In fact, JSP is a good example, JSR-45 sample is a JSP.

JSP debugging has been dependent on the implementation of a specific application server, there is no unified model, JSR-45 for this situation, provides a standard model. We know that JAVA debugging, mainly based on the line number as a sign, positioning. But after the JSP is compiled into Java code, the Java line number and the JSP line number can not correspond to each other, how to solve it.

JSR-45: When JSP is compiled into Java code, it generates a copy of the JSP filename and the corresponding table (SMAP) between the line number and the Java line number. After the JVM receives the debug client request, it can convert from the line number of the JSP to the line number of the JAVA code according to the corresponding table (SMAP), and before the JVM emits the event notification, it also converts the JSP file name and line number to the debug client directly, before the SMAP.

We did a test with Tomcat 5.0, with two jsp,hello.jsp and Greeting.jsp, the former being include the latter. Tomcat compiles them into Java code (HELLO_JSP.JAVA), Java Class (Hello_jsp.class), and the corresponding table (SMAP) between the JSP file name/line number and the Java line number.

HELLO.JSP:


GREETING.JSP:

1 Hello there!<p> 2 Goodbye on <%= new Java.util.Date ()%>

JSP compiled after the Hello_jsp.java is as follows:


Tomcat compiles this JAVA code into Hello_jsp.class, which is located in the $Tomcat _install_path$/work/standalone/localhost/_ directory. But where is the JSP filename/line number and the corresponding table for the JAVA line number (hereinafter referred to as SMAP). The answer is that it is stored in Class. If you open this Class file with UltraEdit, you can find the Sourcedebugextension property, which is used to save the SMAP.

The JVM specification defines the classfile that can contain sourcedebugextension properties and save SMAP:


I used javassist to do a test (javassist is a good thing, it can dynamically change the structure of class, JBOSS AOP on the use of javassist, where we only use it to read Classfile properties)


This code shows the Sourcedebugextension property and you can see the contents of the SMAP. After compiling the JSP, SMAP is written into Class, and you can also use Javassist to modify the Classfile properties.

The following is the SMAP content saved in Hello_jsp.class:


First mention the name of the Java code: Hello_jsp.java, then the stratum name: JSP. The following are the names of two JSP files: hello.jsp, greeting.jsp. Two JSP files a total of 10 lines, resulting in a total of 69 lines of hello_jsp code. The last and most important thing is the corresponding relationship between the source file file name/line number and the target file line number (part between *l and *e)

This format is defined in the specification:

source file line number # source code, repeat number: Destination file start line number, target file line number per increment
(Inputstartline # Linefileid, Repeatcount:outputstartline, outputlineincrement)

The source file line number (inputstartline) destination file start line number (Outputstartline) is required. The following is a specific description of the SMAP:






Back to the top of the page


Develop a JSP editor

Eclipse provides texteditor as the parent class for the text editor. Because the development of Editor is not the focus of this article, do not make concrete exposition. We can use Eclipse's Plugin Project Wizard to build a simple JSP editor:

(1) Click on the File menu, New-> project-> Plug-in project;

(2) Enter the project name Jsp_debug, the next step;

(3) Input plugin ID:com.jsp.debug
Plugin Class Name:com.jsp.debug.JSP_DebugPlugin

(4) Choose to create with template

Using Plug-in with editor, enter
Java Package Name:com.jsp.editors
Editor Class Name:jspeditor
File extension:jsp

A JSP editor is produced.

Run this plugin, create a new Java project, create a new hello.jsp and greeting.jsp, double-click the JSP in Navigator view, and the editor opens.




Back to the top of the page


Set breakpoints in the JSP editor

There are two ways to add breakpoints in the editor, one is to double-click on the vertical ruler on the left of the editor, and the other is to right-click on the left vertical ruler and choose Add/Remove breakpoints from the menu.

In the Eclipse implementation, adding a breakpoint is actually adding a MARKER for ifile, the type is Ibreakpoint.breakpoint_marker, and then the breakpoint is registered to Breakpointmanager.

Breakpointmanager will produce a breakpointrequest that notifies the running JVM target that if the JVM is not started at this time, all breakpoints will be notified to the JVM target together when the JVM is started.

Add a breakpoint use a abstractruleractiondelegate, overload the CreateAction method, and return a iaction managebreakpointruleraction action:


In order to add managebreakpointruleractiondelegate to the right mouse menu of the ruler on the left of the text editor and to handle the mouse double-click event on the left ruler, add a definition to the plugin.xml.

To handle a double-click event:


Add right-click menu:


Managebreakpointruleraction is the actual add breakpoint action, the implementation of the Iupdate interface, this action is to determine whether the currently selected row has a breakpoint type of Marker, if there is no creation, if there is, Delete it.


The Update method is called first when clicked, and then it is possible to collect whether the currently selected row has marker (call the Fetchbpmarkerlist method) and, if so, save it in the variable allmarkers. Because managebreakpointruleraction each time a new instance is generated, there is no conflict.

The following is the call stack for update, as you can see that the Update method was invoked in a mouse-click event:


After the Updae is invoked, the Run method is executed, and you can determine whether to delete or add marker according to Allmarkers.isempty ().

When adding a breakpoint, first use Iverticalrulerinfo to get the line number of the mouse click, according to the line number, obtain the description of the row from the Document model Iregion, get the start character position and end character position, create a JSP breakpoint.


Registering a JSP breakpoint supports the JSR-45 specification, and Javastratumlinebreakpoint is provided in Eclipse. However, it is currently a internal implementation and will not be guaranteed to be modified in future versions. Here for simplicity, inherit directly from Javastratumlinebreakpoint.


To see Javastratumlinebreakpoint source code, you can know that when you create a javastratumlinebreakpoint, you do two things:

(1) Create the marker of the breakpoint type and set the marker properties
Resource.createmarker (Markertype);

(2) Registering breakpoints in the breakpoint manager
Debugplugin.getdefault (). Getbreakpointmanager (). Addbreakpoint (this); The breakpoint manager is responsible for generating a breakpointrequest that notifies the running JVM target that if the JVM is not started at this time, all breakpoints will be notified to the JVM target together when the JVM is started.

The following is the code in the Javastratumlinebreakpoint constructor:


When a breakpoint is removed, the corresponding Ibreakpoint is found according to the marker, and Breakpointmanager removed from the Breakpointmanager automatically deletes the marker and notifies the JVM Target.


Jspbreakpoint overloads the Addtotarget (Jdidebugtarget target) method of the parent class. The purpose of overloading this method is to set up different referencetypename and SourcePath based on different application servers. We know that each application server compiles a JSP that produces a Java class name that is different, such as the Java classes named org.apache.jsp generated by Tomcat compilation hello.jsp. hello_jsp, but WebSphere6.0 is Com.ibm._jsp._hello. Only by determining the server type can you know what referencetypename and Souecepath should be. The target name is currently used to determine the application server type by starting the JVM: String targetstring = Target.getlaunch (). Getlaunchconfiguration (). GetName (); If targetstring contains Tomcat, it is considered Tomcat.

After generating the referencetypename, first create a classpreparerequest notification, then remove all the classes from the VM, and then create an Add breakpoint notification if it is the current Class. This is done because it is possible that this Class has not been loaded by the JVM, and it doesn't make any sense to directly notify the JVM. When Class is loaded, the JVM notifies Eclipse that this is the time when the Add breakpoint notification is generated. It is important to note that the sample code for this article gets referencetypename is not perfect:

(1) Only the Tomcat readers are interested in implementing more web containers, such as JBOSS3, WebSphere6.0

(2) Some special cases are not processed such as JSP with path name package, path name or filename with digital JSP






Back to the top of the page


Debug JSP

Now we can debug the JSP.

(1) Running Jsp_debug plugin
First add a run-time Workbench in run-> run and click the Run button, and the Eclipse's plugin development environment will launch a new eclipse, which we created in the newly launched Eclipse, the Jsp_debug Pl The ugin can be used. Create a new Java project Test (note that you must be a Java project), create a new hello.jsp and greeting.jsp, open hello.jsp, double-click the ruler on the left side of the editor, and a breakpoint appears.

(2) Start Tomcat in Debug mode:
Windows starts->, type cmd, and start a command line window:
CD E:/tomcat5_0_5/bin

(My Tomcat is installed in the E:/tomcat5_0_5 directory, JDK is installed in d:/j2sdk1.4.2)


-xdebug-xnoagent-xrunjdwp:transport=dt_socket,address=8888,server=y,suspend=n is started in debug mode, port number is 8888 Classpath to join D :/j2sdk1.4.2/lib/tools.jar, because I'm Tomcat5.0.5, I don't need it if it's 5.5.

(3) Test hello.jsp
Copy hello.jsp and greeting.jsp to the E:/tomcat5_0_5/webapps/root directory and Access hello.jsp http://localhost:8000/Hello.jsp from the browser. If you succeed, you can continue with the following work, and if it fails, check your tomcat settings.

(4) Start remote debugging
Start remote debugging in Eclipse and connect eclipse as a debug client to Tomcat. In the Java perspective, click Run-> Debug to add a Remote Java application named Start Tomcat Server (not wrong because we want to determine the current Web Server type based on this name)
Project is the Test project that was created
Port is 8888, as set when Tomcat is started

You can connect to Tomcat by clicking on the Debug button. Switch to the debug perspective, and in the Debug view, you can see a list of all the Tomcat threads.

(5) Debugging hello.jsp
Add a breakpoint to hello.jsp and then access hello.jsp from the browser to hang at the breakpoint. You can use Single-step, or you can view variable information in a JSP in the variables view.
Because of Eclipse's own implementation, there is a problem with the JSP Editor now, stepping into the include JSP line and then executing again from HELLO.JSP's 1 lines. This is because the Eclipse JDT debug View caches the Editor,stackframe that are already open in stackframe and does not recalculate the other resource that is currently being debugged. Should have opened the greeting.jsp, but now from the 1th line of hello.jsp began to execute.




Back to the top of the page


Conclusion

Many integrated development environments support JSP debugging, and plug-ins like MyEclipse in Eclipse accomplish similar functions. However, before the JSR-45 specification is produced, each application server has a different implementation of JSP Debug, such as WebSphere 5, which adds two arrays to the JAVA code generated by JSP compilation, representing the corresponding information for the source file and the line number. Tomcat is the first to implement the JSR-45 specification, and WebSphere 6.0 is now taking this pattern, and if you are interested, you can view the WebSphere 6.0 compiled Class, unlike Tomcat, where SMAP files can be generated concurrently with Java code.

However, before starting the server, you need to set JVM parameters Was.debug.mode = True

Set in Ibm-web-ext.xmi at the same time


Using the rationale of this article, we can also develop other JAVA scripting language editors, such as Groovy, to add Debug functionality to the compiler.




Back to the top of the page


Download

name size Download Method
Debug.zip KB HTTP
Jsp_debug_project.zip 280 KB HTTP
Information about the Download method Get adobe®reader®




Back to the top of the page


Resources JPDA
http://java.sun.com/j2se/1.4.2/docs/guide/jpda/

JSR-45
http://www.jcp.org/en/jsr/ detail?id=45

IBM expert Scott Johnson's article
WebSphere application Server V6 JavaServer Pages
http://www-128.i bm.com/developerworks/cn/websphere/techjournal/0412_johnson/0412_johnson.html
 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.