Part 1 of this article series on JavaServer Pages (JSP) in WebSphere Application Server V6 described the internal operations, configuration parameters, and process of the new batch compiler. Part 2 looked at the performance tuning options available for the JSP engine, and showed how to simplify deployment and improve run time performance with predeployed applications. Finally, in Part 3, we are ready to examine the architecture of the new JSP engine.
First, though, this article looks at several ways the JSP 2.0 specification was extended over the prior specification. The JSP engine in WebSphere Application Server V6 supports the JavaServer Pages 2.0 specification, which was finalized in November 2003. The JSP 2.0 specification extended the prior 1.2 specification in several significant ways, by adding:
- An Expression Language for accessing data from JSP pages that was originally developed for JSTL 1.0 and is now incorporated into the JSP 2.0 Specification.
- A new type of custom tag API, the Simple Tag Extension API, which has a less complicated lifecycle than that of classic tag handlers, is easier to work with, and enables tag handlers to be written in JSP syntax as well as in Java™.
- JSP Fragments, which are portions of a JSP page that can be used by a tag handler to produce customized content.
- Improved XML syntax for JSPs delivered as XML documents.
The WebSphere Application Server V6 JSP container was modified significantly to support the requirements of the JSP 2.0 specification, and to improve its performance and configurability. (In this article, the terms JSP engine and JSP container will be used interchangeably.) The most significant changes include:
- Introduction of a new translation framework.
- Tighter run time integration with the WebSphere Application Server V6 Web container.
- New options for controlling the classloading of JSP classes.
Each of these areas will be discussed in the sections that follow.
We start with an overview of the JSP container's roles within WebSphere Application Server to help set the stage for a discussion of the JSP container's architecture. In WebSphere Application Server, we make a distinction between the Web container and the JSP engine; their roles are distinct. In general, the distinction we make is that the JSP engine knows everything about processing JSP resources, while the Web container knows everything about handling servlets and nearly nothing about JSP resources.
The JSP 2.0 specification does not make a distinction between a JSP container and a Web container. In fact, the specification reads:
| "A JSP container is a system-level entity that provides life-cycle management and runtime support for JSP pages and servlet components. Requests sent to a JSP page are delivered by the JSP container to the appropriate JSP page implementation object. The term Web container is synonymous with JSP container." |
In WebSphere Application Server, most of the JSP specification's requirements are provided by the JSP engine, while some are provided by the Web container. Table 1 lists the roles of a JSP container, and the implementer of those roles in WebSphere Application Server V6.
Table 1. Roles of a JSP container
| Role of JSP container | Implementer in Websphere Application Server V6 |
| Validate the syntax of JSP pages and documents; translate valid JSP pages and documents into Java code and compile them into servlet classes (the JSP page implementation classes). | Implemented entirely by the JSP container. |
Run time request handling for JSP resources:
| JSP container will create a custom classloader for the requested JSP page when JSP run time compilation and reloading are enabled. This custom classloader enables reloading of JSP pages at run time. Web container will use the context classloader instead of a custom JSP classloader under certain configuration scenarios:
|
Run time request handling for JSP resources:
| Implemented entirely by the Web container. |
| Lifecycle management of JSP page servlets, including calling initialize and destroy methods and other container-specific methods. | Implemented entirely by the Web container. |
| Regenerate and reinstantiate the JSP page implementation classes when necessary (such as, when a JSP or its dependencies are modified). | Implemented entirely by the JSP container. |
| Provide run time support for JSP classes. | Implemented entirely by the JSP container. |
| Provide support for precompilation of JSP resources. | Implemented entirely by the JSP container. |
| Provide support for debugging as per JSR-045 (Debugging Support for Other Languages). | Implemented entirely by the JSP container. |
JSP container's translation framework
The translation framework manages the processing of a W3C Document Object Model (DOM) object that the JSP container creates from a JSP page or JSP document. The framework provides a structure in which Java classes can be configured to process, or "visit" the elements of a DOM object, and then operate on them.
The typical operations of these visitor classes are:
- Validate that the JSP syntax is correct and report any validation errors. Included files, custom tags, JSP directives and standard actions, and so on, are validated.
- Scan for tag files that are used by the JSP being translated so that the tag files' generated class information (for example, TagFileInfo) can be determined and used by the JSP before the tag file classes themselves are generated.
- Generate a source map (SMAP) for a JSP and insert it into the generated class, if debugging is enabled.
- Generate Java classes for the JSP and the tag files it may use. If the validation process is error-free, Java source is generated for the JSP page and any included tag files.
- Compile the Java classes and report any errors. Tag file source is compiled when the including JSP is processed by javac.
The translation framework is configured by an XML file. This configuration file:
- Associates individual visitor classes with roles or discrete operations. For example, the class ValidateJspVisitor might be associated with the role JspValidate.
- Combines visitor classes into collections that perform sets of operations. For example, the collection DebugJspTranslation might be comprised of the following visitor class roles:
- TagFileDependencyCheck
- JspValidate
- JspGenerate
- Smap.
When a JSP needs to be processed, the JSP container creates an instance of the JspTranslatorFactory class and passes it the name of the desired visitor class collection. The factory returns an instance of a JspTranslator class that is configured to perform the roles defined by the collection.
For example, the JspTranslator configured by the DebugJspTranslation collection will perform JSP and tag file validation and Java source generation, followed by generation of an SMAP that meets the requirements of JSR-045 for source level JSP debugging. The visitor class collection JspTranslation might be the same as the DebugJspTranslation collection, minus the Smap role.
The visitor classes have a well-defined mechanism for communicating with each other. For example, the TagFileDepenencyCheck visitor might populate a complex object that identifies all the properties of a tag file that were discovered during tag file validation. This object would be passed along to subsequent JSP visitor classes that will use the object during JSP validation and Java source code generation.
The configurability of the JSP translation framework enables the JSP container to be modified more quickly in response to new requirements. Such requirements might come from a future JSP specification, or elsewhere. For example, a collection of custom visitor classes could be written to gather optimization data to enhance the generation of the Java source. These new classes would be associated with a role, and that new role would be added to a visitor collection. Using the visitor class communication mechanism, the optimization data would be passed along to the existing visitor classes that generate Java source code and which have been modified to use this information.
The configuration of the JSP translation framework is not exposed to customer Web applications whose needs are met by the standard configurations that support the JSP 2.0 specification.
The JSP container's run time role
In previous versions of WebSphere Application Server, the JSP container's run time processor was implemented as a gateway servlet. For example, in WebSphere Application Server V5, the gateway servlet, implemented by the class JspServlet, was instantiated by the Web container and was configured to handle requests for resources with JSP extensions. When a JSP request was received by the Web container, the request was dispatched to the JspServlet which, in turn, delivered the request to the correct JSP. The JspServlet not only had to implement JSP-specific functionality, but also had to duplicate Web container functionality, such as:
- Manage the JSP class lifecycle, from initialization to destruction.
- Set up Performance Monitoring Infrastructure (PMI) hooks.
- Set up servlet lifecycle listener hooks.
- The gateway servlet itself was a container as it stored all the references to the JSPs that it loaded.
In WebSphere Application Server V6, the JspServlet gateway servlet is no longer used. Functionality is no longer duplicated between the JSP and Web containers. In addition, there is a shorter path between the time when a JSP request is received by the Web container and when the response is returned by the JSP page implementation servlet.
WebSphere Application Server V6 employs a "Web extension processor" architecture in which a JSP extension processor replaces the JspServlet gateway servlet. The Web container instantiates one JSP extension processor for each Web module that it loads. In turn, the JSP extension processor creates one servlet wrapper object for each requested JSP. The JSP extension processor and JSP servlet wrappers are responsible for performing the actions in Table 2. (If a JSP is configured as a servlet in web.xml using the <servlet-class> tag, the JSP extension processor is never invoked during requests for that JSP.)
Table 2. Actions taken by the JSP extension processor and JSP servlet wrapper
| When this occurs | JSP extension processor does this: | JSP servlet wrapper does this: |
| The first request for a JSP is received by the Web container and passed along to the JSP extension processor. | JSP extension processor creates a JSP servlet wrapper for the requested JSP and returns the wrapper to the Web container. The Web container holds on to this wrapper and associates it with the request URI for that JSP. | When handling the first request for a JSP, the JSP servlet wrapper may need to:
Configuration options for the JSP container may alter this behavior. (See JSP classloading.) |
| The second and all subsequent requests for a JSP are received by the Web container. | JSP extension processor is not invoked. | The JSP servlet wrapper is directly invoked by the Web container for the purpose of seeing if the JSP needs to be re-translated due to modification. Depending on the JSP container configuration, the JSP servlet wrapper will re-translate the JSP and create a new page implementation servlet as necessary. In any case, the wrapper will invoke its parent class, ServletWrapper, which will pass the request along to the page implementation servlet for servicing. |
Figure 1 depicts a high-level view of the relationship between the Web container and a JSP extension processor.
Figure 1. Each Web module is given a unique JSP extension processor
The JSP extension processor is a pluggable component of the Web container. The JSP extension processor is just one of several types of extension processors in WebSphere Application Server V6.
Extension processors are instantiated by extension processor factories. For example, a Web module's JSP extension processor is instantiated by a global JSP extension processor factory. Extension factories register themselves with the application server's Web container as the Web container is being started.
Once the Web container has started, it has a list of all registered extension factories. As the Web container loads individual Web modules, this list of available extension processor factories is traversed. The extension processor factory returns an instance of an extension processor that is then associated with one or more URL patterns that it will handle in that particular Web module. These URL patterns are supplied by the extension processor and its factory. The factory supplies standard extensions, and the extension processor supplies extensions particular to the Web module that it will service. Note that different configuration options in any two given Web modules could result in an extension processor handling different URL patterns in each Web module, or could even result in a processor being loaded in one Web module but not in another.
Figures 2 through 4 depict the creation of a JSP extension processor and its role in request handling.
Figure 2. Registering the JSP extension factory during Web container startup
Figure 3. Instantiation of the JSP extension processor during Web module loading
Figure 4. Servlet wrapper instantiation during request processing
- How JSPs classes are loaded
A JSP class can be configured to be loaded by either the JSP engine's classloader or by the Web module's classloader.
By default, a JSP class is loaded by an instance of the JSP engine's classloader, which enables run time reloading of a JSP class when the JSP source or, optionally, one of its dependents, is modified. By default, each JSP is loaded by a unique instance of the JSP engine's classloader. This allows a single JSP class to be reloaded when necessary, without affecting any other loaded JSP classes.
JSP classes will be loaded by the Web module's classloader under either of the following scenarios:
- The JSP engine configuration parameter
useFullPackageNamesis set to true, and the JSP is configured as a servlet inweb.xmlusing the<servlet-class>scenario in Table 2. - The JSP engine configuration parameters
useFullPackageNamesanddisableJspRuntimeCompilationare both set to true. A JSP does not need to be configured as a servlet inweb.xmlin this case.
- The JSP engine configuration parameter
- Configuring JSPs as servlets
A JSP can be configured as a servlet in
web.xml. There are two ways to do this, described below in Table 3. Before configuring a JSP as a servlet, though, consider the following:- Reloading capability
If run time reloading of JSPs is required, requests for JSPs must be handled by the JSP engine. The<servlet-class>scenario in Table 3 would disable run time JSP reloading, while the<jsp-file>scenario would be compatible with reloading. - Reducing the number of classloaders
If run time reloading of modified JSPs is not required, and if limiting the number of classloader instances is desired, then the<servlet-class>scenario in Table 3 can be used. Similarly, scenario B in the previous section can be used without having to configure a JSP as a servlet.
Table 3. Configuring a JSP as a servlet
Scenario Example Compatible with runtime reloading? Multiple classloaders used? useFullPackageNames <jsp-file><servlet>
<servlet-name>jspOne</servlet-name>
<jsp-file>jspOne.jsp</jsp-file>
</servlet>Yes Yes Can be true or false <servlet-class><servlet>
<servlet-name>jspTwo</servlet-name>
<servlet-class>_ibmjsp.jspTwo</servlet-class>
</servlet>No No Must be true The JSP batch compiler tool helps with configuring JSPs as a servlets. When
useFullPackageNamesis true, the JSP batch compiler generates<servlet>and<servlet-mapping>elements for each JSP that it successfully translates and compiles. The elements are written to aweb.xmlfragment file namedgenerated_web.xml, which is located in the binariesWEB-INFdirectory of a Web module processed by the JSP batch compiler (this directory is located within the deployed application's EAR file). All or some of these elements may be copied and pasted into theWEB-INFfile in order to configure JSPs as servlets.It is important to be aware of the location of the
web.xmlthat is being used by the application server. In WebSphere Application Server V6, application-specific configuration is taken from either the application binaries (the application's EAR file) or from the configuration repository. If an application was deployed into WebSphere Application Server with the flagUse Binary Configurationset to true, then theWEB-INF/web.xmlfile is searched for in a Web module's binaries directory, not in the configuration repository:- Example of a configuration repository directory:
{WAS_ROOT}/profiles/profilename/config/cells/cellname/applications/ enterpriseappname/deployments/deployedname/webmodulename - Example of an application binaries directory:
{WAS_ROOT}/profiles/profilename/installedApps/nodename/ EnterpriseAppName/WebModuleName/
If the JSP batch compiler is executed on a pre-deployed application, then the
web.xmlfile is in the Web module'sWEB-INFdirectory. - Reloading capability
- Packages and directories for generated files
By default, the
.javafiles for all JSPs are generated with the package statement:package com.ibm._jsp;The JSP engine's classloader knows how to load JSP classes when they are all in the same package. The
.javafiles themselves are located in the file system within a directory structure mirroring that of the JSP source. If the JSP engine configuration parameteruseFullPackageNamesis set to true, the.javafiles are generated with the package statement:package _ibmjsp.<directory structure in which the jsp is located>;Using full package names enables the configuration of a JSP as a servlet in
web.xml.
Table 4. Examples of packages and directory structures for generated .java and .class files
| JSP file | Java package | Location of .java/.class files in file system | ||
| Default | useFullPackageNames=true | Default | useFullPackageNames=true | |
/myJsp.jsp | com.ibm._jsp | _ibmjsp | / | /_ibmjsp |
/jspFiles/jspOne.jsp | com.ibm._jsp | _ibmjsp.jspFiles | /jspFiles | /_ibmjsp/jspFiles |
/dir with spaces/jspTwo.jsp | com.ibm._jsp | _ibmjsp.dir_20_ with_20_spaces | /dir with spaces | /_ibmjsp/dir_20_ with_20_spaces |
The JSP engine in WebSphere Application Server V6 introduces three major changes from previous releases:
- The configurable translation framework enables the JSP container to be modified more quickly in response to new requirements, such as JSP specification changes and future enhancements.
- The Web extension processor framework enables faster response times by eliminating the JspServlet gateway servlet.
- New classloading options enable customers to configure the JSP engine for optimal performance in both development and production server environments.
The authors wish to thank Arvind Srinivasan, Todd Kaplinger, Kevin Vaughan, and Srinivas Hasti for their contributions to this article.
A note about patent applications
The JSP container's translation framework and the Web container's extension processor framework are subjects of U.S. patent applications filed by IBM.
- To learn more about WebSphere Application Server, visit the developerWorks WebSphere Application Server zone. You'll find technical documentation, how-to articles, education, downloads, product information, technical support resources, and more.
- Browse for books on these and other technical topics.
- WebSphere forums.
Product-specific forums where you can ask questions and share your opinions with other WebSphere users.
- developerWorks blogs. Ongoing, free-form columns by software experts, with space for you to add your comments.
Scott Johnson has been a software developer for 24 years. He joined IBM at the Research Triangle Park Lab in 2000, and was the Team Lead and Architect for the WebSphere Application Server JSP processor for six years. Scott is IBM's representative on the Expert Group for JSR 245, JavaServer Pages 2.1.
Comments (Undergoing maintenance)





