JSP Lifecycle

As has already been stated, JSPs go through a translation and compilation phase prior to processing their first request. This is illustrated in Figure 13.3.

Figure 13.3. JSP translation and processing phase.


The Web server automatically translates and compiles a JSP; you do not have to manually run any utility to do this. JSP translation and compilation can occur at any time prior to the JSP first being accessed. It is implementation dependent when this translation and compilation occurs but it is usually either

  • On deployment

  • When the first request for the JSP is received

If the latter strategy is used, not only is there a delay in processing the first request, because the page is translated and compiled, but if the compilation fails, the client will be presented with some unintelligible error. If your server uses this strategy, ensure that you always force the translation and compilation of your JSP, either by making the first page request after it has been deployed or by forcing the page to be pre-compiled, as shown below.

With J2EE RI, the translation and compilation only takes place when the page is first accessed. You can find the translated JSP under the J2EE Installation directory in

domains/domain1/generated/jsp/j2ee-modules/examples/org/apache/jsp

The generated Java filename will be similar to the original JSP filename. You may find it useful to refer to the translated JSP to understand any compilation errors.

With J2EE RI, you can force the page to be pre-compiled by using your Web browser and appending ?jsp_precompile=true to the JSP's URL string. To pre-compile the request-info.jsp example, you could use the following:

http://localhost:8000/examples/info?jsp_precompile=true

Because the compiled servlet is not executed, there are several advantages:

  • There is no need to add any request parameters to the URL. So you can simply browse the URL rather than access from a form or another Web page.

  • Pages do not have to be compiled in an order determined by the application logic.

  • In a large application, less time is wasted traversing already compiled pages to find non-compiled ones, and it is easier to ensure that pages are not missed.

Realistically, you are going to make errors when writing JSPs. These errors can be quite difficult to comprehend because of the way they are detected and reported. There are four categories of error:

  • JSP translation

  • Servlet compilation

  • Servlet runtime exceptions

  • HTML presentation

The first three categories of error are detected by the JSP container and reported in an implementation-specific way; the J2EE RI reports the error back to the client using HTML. The last type of error (HTML) is detected by the Web browser.

Correcting each category of error requires a different technique and is discussed in this section.

Translation Errors

If you mistype the JSP tags or fail to use the correct attributes for the tags, you will get a translation error that J2EE RI returns to your browser. With the simple JSP that prints out the date, missing the closing % sign from the JSP expression, as in the following code

Today's date is <%= new java.util.Date() >

will generate a translation error. Listing 13.4 shows the code for this JSP, and Figure 13.4 shows the browser output reporting the translation error.

Listing 13.4. dateError.jsp
<HTML>
<HEAD><TITLE>JSP Date Example</TITLE> </HEAD>
<BODY>
  <BIG>
    Today's date is <%= new java.util.Date () >
  </BIG>
</BODY>
</HTML>

Figure 13.4. Browser showing JSP translation error.


NOTE

Using the Web browser to report errors is an expedient solution to the problem of reporting errors, but this approach is not used by all J2EE Containers. Some simply write the error to a log file and return an HTTP error to the browser. The JSP specification simply requires the Web server to report the HTTP 500 status code if there is an error on the JSP.


The error in Figure 13.4 shows a parse error defining an unterminated <%= tag on line 5 of the dateError.jsp page. The line that identifies the source of the error is

org.apache.jasper.compiler.ParseException: /dateError.jsp(5,23) Unterminated <%= tag

This shows all of the useful information for determining the error. The first part of the line tells you the exception that occurred:

org.apache.jasper.compiler.ParseException:

In this case, a generic parsing exception reported by the JSP translator. The J2EE RI includes a version of the Apache Tomcat Web server and it is the Jasper container of Tomcat that has reported the error.

The second part of the error identifies the JSP page:

/dateError.jsp

and the third part specifies the line and column number:

(5,23)

You know that the error is on line 5 of the dateError.jsp page.

The final part of the error message is a brief description of the problem:

Unterminated <%= tag

The rest of the error information returned to the Web browser is a stack trace of where the exception occurred in the Jasper translator. This is of no practical use to you and can be ignored.

From the error information you should be able to identify the problem on the original JSP. Depending on the nature of the error, you may need to look at JSP lines prior to the one with the reported error. Sometimes errors are not reported until much later in the JSP. The worst scenario is when the error is reported on the very last line because this means the error could be practically anywhere in the JSP.

Compilation Errors

Compilation errors can occur when you mistype the Java code in a Java scripting element or when you omit necessary page directives, such as import package lists (see the next section). As for JSP translation errors different J2EE containers will report the errors in their own way. Most will simply write the information to a log file and return an HTTP 500 error to the client. All the JSP specification requires is that the container return a 500 series to the client. The J2EE RI also shows the compilation errors on the page returned to the browser, including the line number in error in the generated file and usually a reference back to the line number in the original JSP file.

NOTE

The December 2003 release of the J2EE RI used when writing this book reports a spurious problem running the Java compiler rather than the actual compilation error. You will need to check the server log file to discover the actual error.


A common mistake is to fail to define the package name for a Java class in a scriptlet or expression, for example:

Today's date is <%= new Date() %>

The following J2EE RI log file extract shows the compilation error that occurs if you make this simple mistake:

[#|2003-12-16T13:31:50.498+0000|SEVERE|j2ee-appserver1.4| org.apache.jasper.compiler
.Compiler|_ThreadID=13;| Error compiling file: /D:/Sun/AppServer/domains/domain1/generated
/jsp/j2ee-modules/examples//org/apache/jspdateJavaError_jsp.java
    [javac] Compiling 1 source file
    [javac] D:SunAppServerdomainsdomain1generatedjspj2ee-modulesexamplesorg
apachejspdateJavaError_jsp.java:45: cannot resolve symbol
    [javac] symbol  : class Date
    [javac] location: class org.apache.jsp.dateJavaError_jsp
    [javac]       out.write(String.valueOf( new Date() ));
    [javac]                                     ^
    [javac] 1 error

If you cannot determine the error from the JSP file, you will need to examine the generated Java file specified in the error message.

Listing 13.5 shows the generated code containing the Java error.

Listing 13.5. Fragment of Generated Java Code
try {
  _jspxFactory = JspFactory.getDefaultFactory();
   response.setContentType("text/html");
   pageContext = _jspxFactory.getPageContext(this, request, response,
                           null, true, 8192, true);
   application = pageContext.getServletContext();
   config = pageContext.getServletConfig();
   session = pageContext.getSession();
   out = pageContext.getOut();
   jspx_out = out;

   out.write("<HTML>
");
   out.write("<HEAD><TITLE>JSP Date Java Error Example");
   out.write("</TITLE></HEAD>
");
   out.write("<BODY>
  ");
   out.write("<BIG>
    Today's date is ");
   out.write(String.valueOf( new Date() ));
   out.write("
  ");
   out.write("</BIG>
");
   out.write("</BODY>
");
   out.write("</HTML>
");
} catch (Throwable t) {
   if (!(t instanceof javax.servlet.jsp.SkipPageException)){
     out = _jspx_out;
     if (out != null && out.getBufferSize() != 0)
       out.clearBuffer();
     if (pageContext != null) pageContext.handlePageException(t);
   }
} finally {
   if (_jspxFactory != null) _jspxFactory.releasePageContext(pageContext);
}

You can use the information provided by the generated code to identify the error in the original JSP. Do not fix the error in the generated file, as this file is replaced when the JSP is next translated.

Java Runtime Exceptions

As part of the code generation process a simple Exception handler is added to the generated code; this can be seen in Listing 13.5. Any exceptions generated by the JSP that are not explicitly caught by try/catch blocks in JSP scriptlets will be reported back to the client as an HTTP 500 error.

In the case of the J2EE RI, a stack trace showing the error is written to the server log file. If the J2EE RI server is running in verbose mode (as discussed on Day 2, “The J2EE Platform and Roles”) a copy of the trace is also displayed in the Server console window.

The JSP specification supports the concept of an error page that can be used to catch JSP exceptions, and this is discussed in more detail in the later sections on “The page Directive” and “Error Page Definition.” The “Error Page Definition” section later in this chapter shows how to write a simple debugging error page for use during JSP development.

HTML Presentation Errors

The last category of error you can make with a JSP is to incorrectly define the HTML elements. These errors must be solved by looking at the HTML returned to the browser; most browsers have a menu option to let you view the HTML source for the page. After the HTML error is identified, you must relate this back to the original JSP file. Adding HTML comments to the JSP file can help you identify the location of the error if it is not readily apparent.

If no HTML data is returned to the browser, you have a serious problem with the JSP that is causing the generated servlet to fail without writing any data. You will need to examine your Web page very carefully for logic errors in the JSP elements; complex scriptlets are the most likely cause of the problem.

Your first step with a JSP that doesn't return HTML is to remove all of the JSP elements, leaving a plain HTML page, and ensure this is correctly displayed by the browser. Gradually re-introduce JSP elements one at a time until the error reappears. Now you can correct the problem when you have identified where it occurs on the page.

JSP Lifecycle Methods

The JSP equivalent of the servlet init() method is called jspInit() and can be defined to set up the JSP page. If present, jspInit() will be called by the server prior to the first request. Similarly, a method called jspDestroy() can be defined to deallocate resources used in the JSP page. The jspDestroy() method will be called when the page is taken out of service.

These methods must be defined inside a JSP declaration, as shown in the following:

<%!
  public void jspInit() {
    ...
  }
  public void jspDestroy() {
    ...
  }
%>

One of the problems with these lifecycle methods is that they are often used to initialize instance variables. Because JSPs are really servlets, the use of instance variables can cause problems with the multi-threading mechanisms used by the Web server for handling multiple page requests. As previously mentioned, access to servlet instance variables should be protected by synchronized blocks.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.19.147