Sunday, February 12, 2006

jsp: How To Display A StackTrace In The Browser Window

Introduction

Debugging Java web based applications is often a slow and tedious task, since we need to keep looking for error messages in the log files. This article demonstrates a technique to direct stacktraces caused by Java exceptions to the browser, potentially saving us a lot of time.

Directing Stack Trace Output To The Browser

Those of us that have been writing Java web applications since before JSPs existed may fondly (or not so fondly) remember how those applications used to be written in the "good old days". Basically, to generate HTML output, a developer had to embed HTML code into a String, and pass that String to as a parameter to the javax.servlet.ServletOutputStream.print() class. This practice led to the creation of lots of hard to maintain applications, which in turn encouraged Sun to develop the JSP specification, but I digress. If we can find a way to pass a stack trace as a parameter to this method, then we can achieve our goal and be able to debug our applications a lot faster.

Looking at the API for ServletOutputStream, there is no method we can use to directly output the stack trace to the browser. Going the other way, looking at the java.lang.Exception class, there is no method to be found that would send the stack trace to a String object. What do we do?

PrintWriter To The Rescue

Upon further examination of the Exception class, we can see that we can send the output of the printStackTrace() method to a java.io.PrintWriter object. We know we can use a PrintWriter to populate a java.io.StringWriter object by passing the latter as a parameter to the former's constructor. We also know that the toString method of StringWriter will return a plain old String with its contents. Putting all this knowledge together, we can come up with a way to display a stack trace in the browser.


package net.ensode.buggyservlet;

//imports obviated

public class BuggyServlet extends HttpServlet
{

protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
Object nullObject = null;

try
{
nullObject.toString(); //force an exception
}
catch (JRException e)
{
// display stack trace in the browser
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
e.printStackTrace(printWriter);
response.setContentType("text/plain");
response.getOutputStream().print(stringWriter.toString());
}
}
}

After running this servlet, we are "greeted" with a stack trace on the browser. By using this technique our servlet debugging will go much faster from now on.

No comments: