Servlet Debugging
Testing and debugging Servlets can be a challenging aspect of the development process. Servlets often involve extensive client/server interactions, which can lead to errors that are difficult to reproduce.
Here are some tips and suggestions to help you debug.
System.out.println()
System.out.println() is used as a marker to test whether a specific piece of code is being executed. We can also print the values of variables. Additionally:
Since the System object is part of the core Java objects, it can be used anywhere without the need to install any additional classes. This includes Servlets, JSPs, RMI, EJBs, plain Beans and classes, as well as standalone applications.
Unlike stopping at breakpoints, writing to System.out does not interrupt the normal execution flow of the application, making it particularly valuable when timing is critical.
Here is the syntax for using System.out.println():
System.out.println("Debugging message");
All messages generated by the above syntax will be logged in the web server's log file.
Message Logging
Using appropriate logging methods to record all debug, warning, and error messages is a good idea. It is recommended to use log4J to log all messages.
The Servlet API also provides a simple way to output information using the log() method, as shown below:
// Import necessary Java libraries
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class ContextLog extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
java.io.IOException {
String par = request.getParameter("par1");
// Call two ServletContext.log methods
ServletContext context = getServletContext();
if (par == null || par.equals(""))
// Log version with Throwable parameter
context.log("No message received:",
new IllegalStateException("Missing parameter"));
else
context.log("Here is the visitor's message: " + par);
response.setContentType("text/html;charset=UTF-8");
java.io.PrintWriter out = response.getWriter();
String title = "Context Log";
String docType = "<!DOCTYPE html> \n";
out.println(docType +
"<html>\n" +
"<head><title>" + title + "</title></head>\n" +
"<body bgcolor=\"#f0f0f0\">\n" +
"<h1 align=\"center\">" + title + "</h1>\n" +
"<h2 align=\"center\">Messages sent</h2>\n" +
"</body></html>");
} //doGet
}
The ServletContext logs its text messages to the servlet container's log file. For Tomcat, these logs can be found in the <Tomcat-installation-directory>/logs directory.
These log files indeed provide an indication of the frequency of new errors or issues. For this reason, it is recommended to use the log() function in the catch clause for exceptions that usually do not occur.
Using JDB Debugger
You can use the jdb command, which is used to debug applets or applications, to debug Servlets. To debug a Servlet, we can debug the sun.servlet.http.HttpServer and treat it as the HttpServer executing the Servlet to respond to HTTP requests from the browser. This is very similar to debugging an applet. Unlike debugging an applet, the actual program being debugged is sun.applet.AppletViewer.
Most debuggers automatically hide the details of how to debug an applet. Similarly, for servlets, you must help the debugger perform the following actions:
Set your debugger's classpath to locate sun.servlet.http.Http-Server and related classes.
Set your debugger's classpath to locate your servlet and supporting classes, usually in server_root/servlets and server_root/classes.
You typically do not want server_root/servlets in your classpath because it disables servlet reloading. However, this inclusion rule is useful for debugging. It allows your debugger to set breakpoints in the servlet before the custom servlet loader in HttpServer loads the servlet.
If you have set the correct classpath, you can start debugging sun.servlet.http.HttpServer. You can set breakpoints in the servlet code you want to debug, then use a web browser to send a request to the HttpServer with the given servlet (http://localhost:8080/servlet/ServletToDebug). You will see the program stop at the breakpoint.
Using Comments
Comments in the code help with debugging in various ways. Comments can be used in many other ways during the debugging process.
This servlet uses Java annotations and single-line comments (//...), multi-line comments (/* ...*/) can be used to temporarily remove parts of Java code. If the bug disappears, carefully review the code you just commented out and identify the issue.
Client and Server Headers
Sometimes, when a servlet does not behave as expected, it is useful to view the raw HTTP request and response. If you are familiar with HTTP structure, you can read the request and response to see what the headers are.
Important Debugging Tips
Here are some servlet debugging tips:
Note that server_root/classes does not reload, while server_root/servlets might.
Request the browser to display the raw content of the page it is showing. This helps identify formatting issues. It is usually an option under the "View" menu.
Ensure the browser has not cached the output of a previous request by forcing a full page reload. In Netscape Navigator, use Shift-Reload, and in Internet Explorer, use Shift-Refresh.
Confirm that the servlet's init() method accepts a ServletConfig parameter and calls super.init(config).