XSLT Debugger for NetBeans

Overview

This is a work in progress copied from the old java.net framework. Apologies that there is no navigation yet!

The latest release is 1.4.1. It contains new features to make it easier to setup Tomcat servers for Remote debugging (see further down in Remote Setup). It also is the first version that requires a 1.5 JVM

Project Description

As the title implies this project is an XSLT debugger that is integrated with the NetBeans IDE as a Netbeans plugin. It offers a good swath of NetBeans debugger functionality to developers of XSL transformations. The project's owner can be contacted at this location: smokindoug@java.net.

Some Details

If you know both XSLT and the Netbeans Debugger you should be able to use the XSLT Debugger for NetBeans without problem. Installation is via the usual NetBeans plugin install mechanism using nbm files. At the heart of the XSLT Debugger for NetBeans lies the Apache Software Foundation's Xalan XSLT engine.

Requirements

This project was started back in the days of NetBeans 5.5. It has sinced moved on to NetBeans 6.9. As of release 1.3.10 it is believed that no post NetBeans 5.5 API have been used, but this has not been tested. A known NetBeans 5.5 (6.0?) issue effects text highlighting. 1.3.10 is compiled as Java 1.4 source and runs under 6.5 (6.8) NetBeans. Release 1.4.1 is compiled as Java 1.5.0 and has NetBeans 6.9 dependencies. Older versions of NetBeans will have to be upgraded.

Downloads

Installation

 Download the .zip file and unzip it, then from the NetBeans Plugins dialog's Downloaded tab select Add Plugins... browse to the unzip directory and select all the unzipped .nbm files. Select Open and follow the directions. You may be told that Xerces libary was already installed--this is OK. After the install NetBeans will want to restart. Once restarted you can start debugging!

Issues

To submit a project issue, or query existing issues, click here

Some things to beware of:

Logging

If you are experiencing problems it can be useful to adjust logging levels. The XSLT Debugger uses the java.util.logging infrastructure and typically creates a Logger per package. For Local Debugging is is usually adequate to adjust the logging level for the dougmcneil.name.xslt.debugger package. For Remote Debugging (where logging is often very helpful) the packages you may want to adjust are: dougmcneil.name.xslt.debugger.container and dougmcneil.name.xslt.debugger.events.

Local Debugging

Using the process outlined here it is possible to directly debug XSLT within the NetBeans IDE.

While learning how to use the XSLT Debugger it helps to be familiar with XSLT and the Netbeans IDE (in particular debugging within NetBeans), but even if your experience with XSLT and NetBeans is limited any experience garnered using other debugging tools should stand you in good stead.

Much of the information on this page is oriented towards using the NetBeans debugger GUI as it specifically relates to the XSLT Debugger. As such it is germane to Remote Debugging as well as Local Debugging and the Remote Debugging page refers to this page for particulars in that regard.

First to be discussed is the window that serves as the central control point for both Local and Remote debugging the XSLT Debugger Options Window.

XSLT Debugger Options Window

The XSLT Debugger Options Window can be accessed from the menu system: Windows -> Debugging -> Open XSLT Debugger Options Window. An example of the XSLT Debugger Options Window is shown below:

XSLT Debugger Options Window

You use the Local tab of the XSLT Debugger Options Window to select the file you want to debug. Since XSLT is what is being debugged a XML Source (typically with a .xml extension) file to transform is required and a XSLT Script (typically with a .xsl extension) that specifies the transformation is required. Also, since the transformation generates output and ouput file name is required (if the output text box is empty when a XML Source file is choosen, the output file is generated by appending _output to the name of the XML Source file). You can have the output file overwritten by checking the Overwrite Output checkbox.

Use the Transform button to launch the XSLT Debugger on the selected XML Source file and XSL Script file. The act of debugging is explained in details further on, but first let's discuss some other ways to launch the XSLT Debugger.

Other Ways to Launch the XSLT Debugger

Any XML or XSL file open in the editor will have a XSLT Debugger launch icon in their toolbar. When pressed the XSLT Debugger Options Window will open (or be fronted if already open) with the appropriate file name filled in the appropriate text box.

XSLT Debugger Options Window

You can also select a XML Source file or a XSLT Script file in any data loader window (Projects, Files, etc.) and use the context menu's Debug... action to open the XSLT Debugger Options Window. If a XML Source file and a XSLT Script file are selected when the context menu's Debug... is activated then the XSLT Debugger Options Window is opened and the XSLT Debugger is launched with using these files. This is shown below:

XSLT Debugger Options Window

XSLT Debugger

The XSLT Debugger provides support for most of the features available while using the NetBeans Debugger framework for debugging Java for instance.

Like debugging a Java file, when the XSLT Debugger is launched the XML Source file and the XSL Script file are opened in the editor (or fronted if already opened -- since there are always two files--at least-- involved with the XSLT Debugger it is a good idea to seperate them into differen editor panes). Also, the windows in the debugger group are opened these may include:

Breakpoints

From the Breakpoints window you can view breakpoints set as described below. You can enable/disable any breakpoint or you can delete particular breakpoints (there is currently no support for creating a breakpoint from the Breakpoints window).

You set a breakpoint from the editor either by clicking in the gutter at the line you wish the breakpoint to be or selecting a line and using the Toggle Line Breakpoint context menu action (or the keyboard shortcut CTRL/F8).

Below is an example of the Breakpoints Window and a couple of snippets of breakpoints set in XML Source and XSL Script files.

XSLT Debugger Options Window

Call Stack

From the Call Stack window you can see what is happening on the XSLT call stack. Every time a XSLT template is invoked via a xsl:apply-templates or an xsl:call-template or a xsl:import-templates instruction an entry is pushed on the XSLT call stack (the xsl:for-each instruction is also treated as an invocation on a psuedo-template that is composed of its contents). The Call Stack has a entry for each invocation on the stack with the last entry shown at the top of the list (there will always be two entries at the bottom of the stack: the first template called and the default template the transformer begins with). Each stack item on the list is identified by it call-signature which is basically the invoking instruction.

Each stack item has a context menu. You can:

Either will highlight the line in question and bring the containing file to the front (good if you are deep in the stack and have many include or imported XSLT Script files open).

XSLT Debugger Options Window

Local Variables

The Local Variables window displays the current XSLT variable that are in-scope. Variable are divided into three types:

  1. Global
  2. Local
  3. Selection

Global variables once evaluated are always available (globals are lazy loaded, they are only evaluated when needed).

Local variables are sub-typed with a name if they are defined within the context of another variable (there is a psuedo-context for the base local variables called __base__document__).

There is only one Selection that refers to the XSLT concept of the current node (as far as can be determined).

XSLT Debugger Options Window

Variables can be viewed as tooltips as well as on the Local Variables window. Hover the cursor over a variable name and if it has been set you will see its value displayed as a tooltip. Note that  hovering the cursor over a "." or "select" will display the selection variable as a tooltip.

XSLT Debugger Options Window

Checkout this Sometime hovering over variable does not provide value via tooltip for problems with tooltips.

Watches

From the Watches window you can view any watches that have been set. When a watched variable is set the debugger will break. When creating watches append the variable type to the end if there are naming clashes, e.g. newcontent.global.

XSLT Debugger Options Window

Output

While the transformation is being debugged its output is written to the Output window. Transformation output also goes to the output file, but since it comes from the debug events it allows you to correlate better with debug actions. Due to the nature of the events and the output options you might notice output lag while stepping through a transformation. Usually it is not a problem and there is more discussion later of the few oddities in the GUI and the interaction with the transformation being debugged.

XSLT Debugger Options Window

XSLT Debugger in Action

In this section the various actions that constitute a XSLT Debugger session are discussed. As mentioned the usual debugger actions like single stepping are available with their attendant GUI feedback. The best way of presenting  these capabilities is with examples like the ones below:

XSLT Debugger Options Window

 The image exhibits most of the markings associated with the XSLT Debugger seen in an editor window:

Actions

There are several XSLT Debugger actions that are available depending on debugger state. When stopped at a breakpoint the debugger toolbar looks somthing like below:

XSLT Debugger Options Window

The actions from left to right (all have keyboard shortcuts):

Finish

Abort the debugging and the transformation.

Pause

Break wherever the transformation is currently executing front the script windows and the source window highlighting the cursor position.

Continue

Continue from a break.

Step Over Line

Step over a line of script.

Step Into Expression

If there are more than one XSLT instruction on a line use this action to step into successive instructions. Also, if the XSLT instruction has makes a selection this  action steps into the delivery of the selection so that the selection variable is synced with the instruction's selection. The instruction highlighting changes colour to a light green (hover over a "select" to see the selection variable as a tooltip).

Step Into Template

Stepping into a template enters the template (instead of stepping over the template).

Step Out of Template

When in a template step to the instruction after the call to the template.

Continue to Cursor

Continue, breaking at the first XSLT script line where a editor cursor has been placed.

Remote Debugging

With Remote Debugging transformations occurring in remote Java Virtual Machine instances (remote to the NetBeans IDE) can be debugged. This can be beneficial when it is important to debug the XSLT transformation in some type of complex operational environment, perhaps where source is being dynamically generated or there is use of XSLT extension functions that require special setup or debugging production systems. The XSLT Debugger was first developed to debug XSLT transformations executed as part of Servlets running in Tomcat. But support for other environments has been strengthened with the most recent being Cocoon. This page will concentrate on debugging transforms running in the Tomcat J2EE container.

XSLT Debugger Options Window

 As remote debugging is being discussed we are interested in the Remote tab of the XSLT Debugger Options Window as shown below:

The NetBeans IDE JVM executing the XSLT Debugger GUI communicates over sockets with the remote JVM running the XSLT transformation. Therefore the Server textbox shown with localhost entered in it. You can also supply a port as in localhost:3010. The default port is 3000. So far so good. Now lets talk about the other controls

The XSLT Debugger is architecturally split into a part that provides the debugging GUI based on events that are received from a debugging engine part. There is a local engine that provides the events for Local Debugging and a remote engine that provides events for Remote Debugging (plus a communcations protocol component linking both parts). Ignoring the complexity of XSLT transformation events the local engine is quite simple as it only support a simple transformation of a XSLT source file and a XSLT script file. The remote engine is more complex since it integrates into some unknown code performing XSLT transformations, it basicly intercepts the transformations and executes them through its own transformation engine (xalan). It does this by providing its own implementation of javax.xml.tranformer.TransformerFactory. So lets discuss how this works on the server side.

Server

The image below shows a NetBeans Tomcat server's properties dialog.

 

Here you can see that a VM system property is defined: javax.xml.transform.TransformerFactory and set equal to dougmcneil.name.xslt.debugger.container.TransformerFactory. This says than whenever a process running in the Tomcat JVM requests a transformation using the JAXP API it will use the implementation defined in dougmcneil.name.xslt.debugger.container.TransformerFactory to provide instances of javax.xml.transform.Transformer. These will be instances of the class dougmcneil.name.xslt.debugger.container.TransformerFactory$Transformer which wraps the xalan implementation and provides the capability to send transformer events to the NetBeans IDE JVm waiting at the other end of the socket. If you want to get into the nitty-gritty feel free to download and browse the source!

Ok. But a jar file containing this implementation is required, so where do you find it? When the XSLT Debugger is downloaded and unzipped there are 5 .nbm files. Three of these contain libraries for xalan and its dependencies. One is the XSLT Debugger with support for the debugger GUI and Local Debugging. One is the XSLT Remote Debugger with support for Remote Debugging.

When NetBeans installs the plugin it unpacks the contents and places dependent jar files in the user's NetBeans modules/ext directory. Therefore after installation of XSLT Remote Debugger look in your modules/ext (typically located at $user/.netbeans/$version/modules/ext)  directory for the jar file: RemoteXSLTDebugger.jar. This file will be required on the classpath of the JVM that is performing the transformations, in the case of this discussion Tomcat.

That should be it for configuration. Start up Tomcat and use a browser to execute a text Servlet like the following code snippet:

response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter(); out.println("");
out.println("");
out.println("");
out.println("Servlet RemoteTest");
out.println("");
out.println("");
TransformerFactory factory = TransformerFactory.newInstance();
out.println("Servlet RemoteTest at " + factory.toString() + "");
out.flush();
try {
Transformer transformer = factory.newTransformer(new SAXSource(new InputSource("file:///C:test.xsl")));
out.println("Transformer: " + transformer.toString() + "");
DOMResult result = new DOMResult();
transformer.transform(new StreamSource("file:///C:/test.xml"), result);
} catch (TransformerConfigurationException ex) {
ex.printStackTrace();
} catch (TransformerException te) {
te.printStackTrace();
}
out.println("");
out.println("");

When you access this Servlet from a browser it will load an instance of dougmcneil.name.xslt.debugger.container.TransformerFactory$Transformer which will open a server socket to listen for connections. This is when you press the Connect button on the Remote tab of the XSLT Debugger Options Window. When the accept option is set to Ask as shown in the above image you will get a confirmation dialog something as follows (note: due to some syncing issue between the two communication ends you may need to prime the connection by executing the Servlet twice, once to establish a server listener, then again to launch debugging after establishing a connection---see the issues):

The two ends have completed their handshake and the XSLT Debugger has received a request to debug the transformation on the given files. Hit Ok to launch a debug session. The NetBeans IDE will open the necessary debugging windows and toolbars and the XSLT Debugger Options Window will reflect the debugging status as shown below:

Each remote session is given a number which you see reflected on the status as well as in the output shown below:

 

Advanced usage

 The dougmcneil.name.xslt.debugger.container.TransformerFactory has support for other types of input like DOM. If non-file based input is recognized like DOM it is serialized to temporary files and these files used for transformation versus the non-file input.

There is also some support for javax.xml.transform.sax.TransformerHandler type of processors like Cocoon.

Multiple debugging sessions are supported. Tomcat may process requests for Servlets that perform transformations on many threads. Each XSLT transformation debugging request creates a new debugger session, therefore there may be multiple debugger session active at once.

The interface between the communicating JVMs in remote debugging works with files. File identified by URI. If the NetBeans JVM cannot resolve these URI mapping using "regex" can be tried. If this is not adequate an implementation of the interface dougmcneil.name.xslt.debugger.resolver.Resolver can be provided. It has one method: public URI map(URI from). An implementation is provided: dougmcneil.name.debugger.resolver.resolver.impl.CMSResolver. This resolver works by taking a classpath like string and checking for file matches under the directories defined in the classpath. It takes the first match. The classpath string is defined as a System propertty called: dougmcneil.name.xslt.debugger.resolver.impl.CMSResolver.

Dependents

The transformation on the remote end has only been tested with the following XML and XSLT engines:

Remote Setup

Remote XSLT Debugger Setup Options

In the section Remote Debugging you saw how to manually setup a Tomcat server for remote XSLT debugging. Since release 1.4.1 a new feature that automates much of the process has been added. This new functionality is invoked from NetBeans Misc. Options (Tools -> Options -> Misc -> Remote XSLT Debugger). An example of which is below.

Remote Options

The Servers list is retrieved from the list of configured NetBeans Application Servers. A configured Tomcat server has been selected (only Tomcat servers can be automatically setup for remote debugging) and you see the options available for configuring the server for remote debugging.

You will typically not have to change the port, but if you do, remember you will have to attach to that port as described in Remote Debugging.

To enable the selected Tomcat for Remote XSLT Debugging tick the checkbox and click OK. That's it! Verify that things worked by the output of the process--an example is shown below.

Remote Options output

A bit of a digression on how things work. The Tomcat configuration mechanism is used to inject the setup information required by the XSLT Remote Debugger code. It adds the required jars using the Java extension mechanism (in front of any other extension jars) and it modifies or add various properties required. If the process discovers that there have been previous modifications made to the Tomcat server it will fail and the error will be logged in the output and setup is aborted.

Remote Execution

To support working with automatically setup Tomcat servers as just explained changes to the Remote section of the XSLT Debugger Options Window have been made to support custom Resolvers. A single String argument is now accepted for Resolver Constructors (in addition to the default no argument Constructor). It offers memory and can be used when attaching to various Tomcat servers for special purposes. Below is a screen capture showing the changes.

Remote execution Resolver

Here we see that a Resolver is set as the selected mapper and is constructed with a String path as its argument.

Note that localhost is used as the name of the server to connect to (NetBeans only deals with local servers).

Notes

The Tomcat Server should be down when you change its setting via Remote Setup (in some instances it is brought down for you).