<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<!DOCTYPE document [
  <!ENTITY project SYSTEM "project.xml">
]>
<document url="jasper-howto.html">

    &project;

    <properties>
        <title>Jasper 2 JSP Engine How To</title>
    </properties>

<body>

<section name="Table of Contents">
<toc/>
</section>

<section name="Introduction">

<p>Tomcat <version-major-minor/> uses the Jasper 2 JSP Engine to implement
the <a href="https://cwiki.apache.org/confluence/display/TOMCAT/Specifications">Jakarta Pages 4.0</a>
specification.</p>

<p>Jasper 2 has been redesigned to significantly improve performance over
the original Jasper.  In addition to general code improvements the following
changes were made:</p>
<ul>
<li><strong>JSP Custom Tag Pooling</strong> - The java objects instantiated
for JSP Custom Tags can now be pooled and reused.  This significantly boosts
the performance of JSP pages which use custom tags.</li>
<li><strong>Background JSP compilation</strong> - If you make a change to
a JSP page which had already been compiled Jasper 2 can recompile that
page in the background.  The previously compiled JSP page will still be
available to serve requests.  Once the new page has been compiled
successfully it will replace the old page.  This helps improve availability
of your JSP pages on a production server.</li>
<li><strong>Recompile JSP when included page changes</strong> - Jasper 2
can now detect when a page included at compile time from a JSP has changed
and then recompile the parent JSP.</li>
<li><strong>JDT used to compile JSP pages</strong> - The
Eclipse JDT Java compiler is now used to perform JSP java source code
compilation. This compiler loads source dependencies from the container
classloader. Ant and javac can still be used.</li>
</ul>


<p>Jasper is implemented using the servlet class
<code>org.apache.jasper.servlet.JspServlet</code>.</p>

</section>

<section name="Configuration">

<p>By default Jasper is configured for use when doing web application
development.  See the section <a href="#Production_Configuration">
Production Configuration</a> for information on configuring Jasper
for use on a production Tomcat server.</p>

<p>The servlet which implements Jasper is configured using init parameters
in your global <code>$CATALINA_BASE/conf/web.xml</code>.
</p>
<ul>
<li><strong>checkInterval</strong> - If development is false and checkInterval
is greater than zero, background compiles are enabled. checkInterval is the time
in seconds between checks to see if a JSP page (and its dependent files) needs
to be recompiled. Default <code>0</code> seconds.</li>

<li><strong>classdebuginfo</strong> - Should the class file be compiled with
debugging information?  <code>true</code> or <code>false</code>, default
<code>true</code>.
</li>

<li><strong>classpath</strong> - Defines the class path to be used to compile
the generated servlets. This parameter only has an effect if the ServletContext
attribute org.apache.jasper.Constants.SERVLET_CLASSPATH is not set. This
attribute is always set when Jasper is used within Tomcat. By default the
classpath is created dynamically based on the current web application.</li>

<li><strong>compiler</strong> - Which compiler Ant should use to compile JSP
pages. The valid values for this are the same as for the compiler attribute of
Ant&apos;s
<a href="https://ant.apache.org/manual/Tasks/javac.html#compilervalues">javac</a>
task. If the value is not set, then the default Eclipse JDT Java compiler will
be used instead of using Ant. There is no default value. If this attribute is
set then <code>setenv.[sh|bat]</code> should be used to add
<code>ant.jar</code>, <code>ant-launcher.jar</code> and <code>tools.jar</code>
to the <code>CLASSPATH</code> environment variable.</li>

<li><strong>compilerSourceVM</strong> - What JDK version are the source files
compatible with? (Default value: <code>17</code>)</li>

<li><strong>compilerTargetVM</strong> - What JDK version are the generated files
compatible with? (Default value: <code>17</code>)</li>

<li><strong>development</strong> - Is Jasper used in development mode? If true,
the frequency at which JSPs are checked for modification may be specified via
the modificationTestInterval parameter.<code>true</code> or <code>false</code>,
default <code>true</code>.</li>

<li><strong>displaySourceFragment</strong> - Should a source fragment be
included in exception messages? <code>true</code> or <code>false</code>,
default <code>true</code>.</li>

<li><strong>dumpSmap</strong> - Should the SMAP info for JSR45 debugging be
dumped to a file? <code>true</code> or <code>false</code>, default
<code>false</code>. <code>false</code> if suppressSmap is true.</li>

<li><strong>enablePooling</strong> - Determines whether tag handler pooling is
enabled. This is a compilation option. It will not alter the behaviour of JSPs
that have already been compiled. <code>true</code> or <code>false</code>,
default <code>true</code>.
</li>

<li><strong>engineOptionsClass</strong> - Allows specifying the Options class
used to configure Jasper. If not present, the default EmbeddedServletOptions
will be used.
</li>

<li><strong>errorOnUseBeanInvalidClassAttribute</strong> - Should Jasper issue
an error when the value of the class attribute in an useBean action is not a
valid bean class? <code>true</code> or <code>false</code>, default
<code>true</code>.</li>

<li><strong>fork</strong> - Have Ant fork JSP page compiles so they are
performed in a separate JVM from Tomcat? <code>true</code> or
<code>false</code>, default <code>true</code>.</li>

<li><strong>genStringAsCharArray</strong> - Should text strings be generated as char
arrays, to improve performance in some cases? Default <code>false</code>.</li>

<li><strong>javaEncoding</strong> - Java file encoding to use for generating
java source files. Default <code>UTF8</code>.</li>

<li><strong>keepgenerated</strong> - Should we keep the generated Java source
code for each page instead of deleting it? <code>true</code> or
<code>false</code>, default <code>true</code>.</li>

<li><strong>mappedfile</strong> - Should we generate static content with one
print statement per input line, to ease debugging?
<code>true</code> or <code>false</code>, default <code>true</code>.</li>

<li><strong>maxLoadedJsps</strong> - The maximum number of JSPs that will be
loaded for a web application. If more than this number of JSPs are loaded, the
least recently used JSPs will be unloaded so that the number of JSPs loaded at
any one time does not exceed this limit. A value of zero or less indicates no
limit. Default <code>-1</code></li>

<li><strong>jspIdleTimeout</strong> - The amount of time in seconds a JSP can be
idle before it is unloaded. A value of zero or less indicates never unload.
Default <code>-1</code></li>

<li><strong>modificationTestInterval</strong> - Causes a JSP (and its dependent
files) to not be checked for modification during the specified time interval
(in seconds) from the last time the JSP was checked for modification. A value of
0 will cause the JSP to be checked on every access. Used in development mode
only. Default is <code>4</code> seconds.</li>

<li><strong>recompileOnFail</strong> - If a JSP compilation fails should the
modificationTestInterval be ignored and the next access trigger a re-compilation
attempt? Used in development mode only and is disabled by default as compilation
may be expensive and could lead to excessive resource usage.</li>

<li><strong>scratchdir</strong> - What scratch directory should we use when
compiling JSP pages? Default is the work directory for the current web
application.</li>

<li><strong>suppressSmap</strong> - Should the generation of SMAP info for JSR45
debugging be suppressed? <code>true</code> or <code>false</code>, default
<code>false</code>.</li>

<li><strong>trimSpaces</strong> - Should template text that consists entirely of
whitespace be removed from the output (<code>true</code>), replaced with a
single space (<code>single</code>) or left unchanged (<code>false</code>)?
Alternatively, the <code>extended</code> option will remove leading and trailing
whitespace from template text and collapse sequences of whitespace and newlines
within the template text to a single new line. Note that if a JSP page or tag
file specifies a <code>trimDirectiveWhitespaces</code> value of
<code>true</code>, that will take precedence over this configuration setting for
that page/tag. Default <code>false</code>.</li>

<li><strong>xpoweredBy</strong> - Determines whether X-Powered-By response
header is added by generated servlet. <code>true</code> or <code>false</code>,
default <code>false</code>.</li>

<li><strong>strictQuoteEscaping</strong> - When scriptlet expressions are used
for attribute values, should the rules in JSP.1.6 for the escaping of quote
characters be strictly applied? <code>true</code> or <code>false</code>, default
<code>true</code>.</li>

<li><strong>quoteAttributeEL</strong> - When EL is used in an attribute value
on a JSP page, should the rules for quoting of attributes described in JSP.1.6
be applied to the expression? <code>true</code> or <code>false</code>, default
<code>true</code>.</li>

<li><strong>variableForExpressionFactory</strong> - The name of the variable
 to use for the expression language expression factory. If not specified, the
  default value of <code>_el_expressionfactory</code> will be used.</li>

<li><strong>variableForInstanceManager</strong> - The name of the variable
 to use for the instance manager factory. If not specified, the default value
 of <code>_jsp_instancemanager</code> will be used.</li>

<li><strong>poolTagsWithExtends</strong> - By default, JSPs that use
 their own base class via the extends
 attribute of the page directive, will have Tag pooling disabled since
 Jasper cannot guarantee that the necessary initialisation will have taken
 place. This can have a negative impact on performance. Providing the
 alternative base class calls _jspInit() from Servlet.init(), setting  this
 property to <code>true</code> will enable pooling with an alternative base
 class. If the alternative base class does not call _jspInit() and this
 property is <code>true</code>, NPEs will occur when attempting to use
 tags. <code>true</code> or <code>false</code>, default
 <code>false</code>.</li>

<li><strong>strictGetProperty</strong> - If <code>true</code>, the requirement
 to have the object referenced in
 <code>jsp:getProperty</code> action to be previously "introduced"
 to the JSP processor, as specified in the chapter JSP.5.3 of JSP 2.0 and
 later specifications, is enforced. <code>true</code> or <code>false</code>, default
 <code>true</code>.</li>

<li><strong>strictWhitespace</strong> - If <code>false</code> the requirements
 for whitespace before an
 attribute name will be relaxed so that the lack of whitespace will not
 cause an error. <code>true</code> or <code>false</code>, default
 <code>true</code>.</li>

<li><strong>jspServletBase</strong> - The base class of the Servlets generated
 from the JSPs.If not specified, the default value of
 <code>org.apache.jasper.runtime.HttpJspBase</code> will be used.</li>

<li><strong>serviceMethodName</strong> - The name of the service method
 called by the base class. If not specified, the default value of
 <code>_jspService</code> will be used.</li>

<li><strong>servletClasspathAttribute</strong> - The name of the ServletContext
 attribute that provides the classpath for the JSP. If not specified, the default
 value of <code>org.apache.catalina.jsp_classpath</code> will be used.</li>

<li><strong>jspPrecompilationQueryParameter</strong> - The name of the query
 parameter that causes the JSP engine to just pregenerate the servlet but
 not invoke it. If not specified, the default value of
 <code>jsp_precompile</code> will be used, as defined by JSP specification
 (JSP.11.4.2).</li>

<li><strong>generatedJspPackageName</strong> - The default package name
 for compiled JSPs. If not specified, the default value of
 <code>org.apache.jsp</code> will be used.</li>

<li><strong>generatedTagFilePackageName</strong> - The default package name
 for tag handlers generated from tag files. If not specified, the default
 value of <code>org.apache.jsp.tag</code> will be used.</li>

<li><strong>tempVariableNamePrefix</strong> - Prefix to use for generated
 temporary variable names. If not specified, the default value of
 <code>_jspx_temp</code> will be used.</li>

<li><strong>useInstanceManagerForTags</strong> - If <code>true</code>,
 the instance manager is used to obtain tag handler instances.
 <code>true</code> or <code>false</code>, default <code>false</code>.</li>

<li><strong>limitBodyContentBuffer</strong> - If <code>true</code>, any
 tag buffer that expands beyond the value of the
 <code>bodyContentTagBufferSize</code> init parameter will be
 destroyed and a new buffer created.
 <code>true</code> or <code>false</code>, default <code>false</code>.</li>

<li><strong>bodyContentTagBufferSize</strong> - The size (in characters)
 to use when creating a tag buffer. If not specified, the default value of
 <code>org.apache.jasper.Constants.DEFAULT_TAG_BUFFER_SIZE</code> (512)
 will be used.</li>

</ul>

<p>The Java compiler from Eclipse JDT in included as the default compiler. It is
an advanced Java compiler which will load all dependencies from the Tomcat class
loader, which will help tremendously when compiling on large installations with
tens of JARs. On fast servers, this will allow sub-second recompilation cycles
for even large JSP  pages.</p>

<p>Apache Ant, which was used in previous Tomcat releases, can be used instead
of the new compiler by configuring the compiler attribute as explained above.
</p>

<p>If you need to change the JSP Servlet settings for an application you can
override the default configuration by re-defining the JSP Servlet in
<code>/WEB-INF/web.xml</code>. However, this may cause problems if you attempt
to deploy the application on another container as the JSP Servlet class may
not be recognised. You can work-around this problem by using the Tomcat specific
<code>/WEB-INF/tomcat-web.xml</code> deployment descriptor. The format is
identical to <code>/WEB-INF/web.xml</code>. It will override any default
settings but not those in <code>/WEB-INF/web.xml</code>. Since it is Tomcat
specific, it will only be processed when the application is deployed on
Tomcat.</p>

</section>

<section name="Known issues">

<p>As described in
<a href="https://bz.apache.org/bugzilla/show_bug.cgi?id=39089">
bug 39089</a>, a known JVM issue,
<a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6294277">
bug 6294277</a>, may cause a
<code>java.lang.InternalError: name is too long to represent</code> exception
when compiling very large JSPs. If this is observed then it may be worked around
by using one of the following:
</p>
<ul>
<li>reduce the size of the JSP</li>
<li>disable SMAP generation and JSR-045 support by setting
<code>suppressSmap</code> to <code>true</code>.</li>
</ul>

</section>

<section name="Production Configuration">

<p>The main JSP optimization which can be done is precompilation of JSPs.
However, this might not be possible (for example, when using the
jsp-property-group feature) or practical, in which case the configuration of the
Jasper servlet becomes critical.</p>

<p>When using Jasper 2 in a production Tomcat server you should consider making
the following changes from the default configuration.</p>
<ul>
<li><strong>development</strong> - To disable on access checks for JSP
pages compilation set this to <code>false</code>.</li>
<li><strong>genStringAsCharArray</strong> - To generate slightly more efficient
char arrays, set this to <code>true</code>.</li>
<li><strong>modificationTestInterval</strong> - If development has to be set to
<code>true</code> for any reason (such as dynamic generation of JSPs), setting
this to a high value will improve performance a lot.</li>
<li><strong>trimSpaces</strong> - To remove unnecessary bytes from the response,
consider setting this to <code>single</code> or <code>extended</code>.</li>
</ul>

</section>

<section name="Web Application Compilation">

<p>Using Ant is the preferred way to compile web applications using JSPC. Note
that when pre-compiling JSPs, SMAP information will only be included in the
final classes if suppressSmap is false and compile is true.
Use the script given below (a similar script is included in the "deployer"
download) to precompile a webapp:
</p>

<source><![CDATA[<project name="Webapp Precompilation" default="all" basedir=".">

   <import file="${tomcat.home}/bin/catalina-tasks.xml"/>

   <target name="jspc">

    <jasper
             validateXml="false"
             uriroot="${webapp.path}"
             webXmlInclude="${webapp.path}/WEB-INF/generated_web.xml"
             outputDir="${webapp.path}/WEB-INF/src" />

  </target>

  <target name="compile">

    <mkdir dir="${webapp.path}/WEB-INF/classes"/>
    <mkdir dir="${webapp.path}/WEB-INF/lib"/>

    <javac destdir="${webapp.path}/WEB-INF/classes"
           debug="on" failonerror="false"
           srcdir="${webapp.path}/WEB-INF/src"
           excludes="**/*.smap">
      <classpath>
        <pathelement location="${webapp.path}/WEB-INF/classes"/>
        <fileset dir="${webapp.path}/WEB-INF/lib">
          <include name="*.jar"/>
        </fileset>
        <pathelement location="${tomcat.home}/lib"/>
        <fileset dir="${tomcat.home}/lib">
          <include name="*.jar"/>
        </fileset>
        <fileset dir="${tomcat.home}/bin">
          <include name="*.jar"/>
        </fileset>
      </classpath>
      <include name="**" />
      <exclude name="tags/**" />
    </javac>

  </target>

  <target name="all" depends="jspc,compile">
  </target>

  <target name="cleanup">
    <delete>
        <fileset dir="${webapp.path}/WEB-INF/src"/>
        <fileset dir="${webapp.path}/WEB-INF/classes/org/apache/jsp"/>
    </delete>
  </target>

</project>]]></source>

<p>
The following command line can be used to run the script
(replacing the tokens with the Tomcat base path and the path to the webapp
which should be precompiled):
</p>
<source>$ANT_HOME/bin/ant -Dtomcat.home=&lt;$TOMCAT_HOME&gt; -Dwebapp.path=&lt;$WEBAPP_PATH&gt;</source>


<p>
Then, the declarations and mappings for the servlets which were generated
during the precompilation must be added to the web application deployment
descriptor. Insert the <code>${webapp.path}/WEB-INF/generated_web.xml</code>
at the right place inside the <code>${webapp.path}/WEB-INF/web.xml</code> file.
Restart the web application (using the manager) and test it to verify it is
running fine with precompiled servlets. An appropriate token placed in the
web application deployment descriptor may also be used to automatically
insert the generated servlet declarations and mappings using Ant filtering
capabilities. This is actually how all the webapps distributed with Tomcat
are automatically compiled as part of the build process.
</p>

<p>
At the jasper task you can use the option <code>addWebXmlMappings</code> for
automatic merge the <code>${webapp.path}/WEB-INF/generated_web.xml</code>
with the current web application deployment descriptor at
<code>${webapp.path}/WEB-INF/web.xml</code>.
</p>

<p>
When you want to use a specific version of Java for your JSP's, add the
javac compiler task attributes <code>source</code> and <code>target</code> with
appropriate values. For example, <code>16</code> to compile JSPs for Java 16.
</p>

<p>
For production you may wish to disable debug info with
<code>debug=&quot;off&quot;</code>.
</p>

<p>
When you don't want to stop the JSP generation at first JSP syntax error, use
<code>failOnError=&quot;false&quot;</code> and with
<code>showSuccess=&quot;true&quot;</code> all successful <i>JSP to Java</i>
generation are printed out. Sometimes it is very helpful, when you cleanup the
generate java source files at <code>${webapp.path}/WEB-INF/src</code>
and the compile JSP servlet classes at
<code>${webapp.path}/WEB-INF/classes/org/apache/jsp</code>.
</p>

<p><strong>Hints:</strong></p>
<ul>
<li> When you switch to another Tomcat release, then regenerate and recompile
your JSP's with the new Tomcat version.</li>
<li>Use a Servlet context parameter to disable PageContext pooling
<code>org.apache.jasper.runtime.JspFactoryImpl.POOL_SIZE=-1</code>
and limit the buffering with the JSP Servlet init-param
<code>limitBodyContentBuffer=true</code>. Note
that changing from the defaults may affect performance, but it will vary
depending on the application.</li>
</ul>
</section>

<section name="Optimisation">
<p>
There are a number of extension points provided within Jasper that enable the
user to optimise the behaviour for their environment.
</p>

<p>
The first of these extension points is the tag plug-in mechanism. This allows
alternative implementations of tag handlers to be provided for a web application
to use. Tag plug-ins are registered via a <code>tagPlugins.xml</code> file
located under <code>WEB-INF</code>. A sample plug-in for the JSTL is included
with Jasper.
</p>

<p>
The second extension point is the Expression Language interpreter. Alternative
interpreters may be configured through the <code>ServletContext</code>. See the
<code>ELInterpreterFactory</code> javadoc for details of how to configure an
alternative EL interpreter. A alternative interpreter primarily targeting tag
settings is provided at
<code>org.apache.jasper.optimizations.ELInterpreterTagSetters</code>. See the
javadoc for details of the optimisations and the impact they have on
specification compliance.
</p>

<p>
An extension point is also provided for coercion of String values to Enums. It
is provided at
<code>org.apache.jasper.optimizations.StringInterpreterEnum</code>. See the
javadoc for details of the optimisations and the impact they have on
specification compliance.
</p>
</section>

</body>

</document>
