Jasper 2 JSP Engine How To
Table of Contents
- Introduction
- Configuration
- Known issues
- Production Configuration
- Web Application Compilation
- Optimisation
Introduction
Tomcat 9.0 uses the Jasper 2 JSP Engine to implementthe JavaServer Pages 2.3specification.
Jasper 2 has been redesigned to significantly improve performance overthe original Jasper. In addition to general code improvements the followingchanges were made:
- JSP Custom Tag Pooling - The java objects instantiatedfor JSP Custom Tags can now be pooled and reused. This significantly booststhe performance of JSP pages which use custom tags.
- Background JSP compilation - If you make a change toa JSP page which had already been compiled Jasper 2 can recompile thatpage in the background. The previously compiled JSP page will still beavailable to serve requests. Once the new page has been compiledsuccessfully it will replace the old page. This helps improve availabilityof your JSP pages on a production server.
- Recompile JSP when included page changes - Jasper 2can now detect when a page included at compile time from a JSP has changedand then recompile the parent JSP.
- JDT used to compile JSP pages - TheEclipse JDT Java compiler is now used to perform JSP java source codecompilation. This compiler loads source dependencies from the containerclassloader. Ant and javac can still be used.
Jasper is implemented using the servlet classorg.apache.jasper.servlet.JspServlet
.
Configuration
By default Jasper is configured for use when doing web applicationdevelopment. See the section Production Configuration for information on configuring Jasperfor use on a production Tomcat server.
The servlet which implements Jasper is configured using init parametersin your global $CATALINA_BASE/conf/web.xml
.
- checkInterval - If development is false and checkIntervalis greater than zero, background compiles are enabled. checkInterval is the timein seconds between checks to see if a JSP page (and its dependent files) needsto be recompiled. Default
0
seconds. - classdebuginfo - Should the class file be compiled withdebugging information?
true
orfalse
, defaulttrue
. - classpath - Defines the class path to be used to compilethe generated servlets. This parameter only has an effect if the ServletContextattribute org.apache.jasper.Constants.SERVLET_CLASSPATH is not set. Thisattribute is always set when Jasper is used within Tomcat. By default theclasspath is created dynamically based on the current web application.
- compiler - Which compiler Ant should use to compile JSPpages. The valid values for this are the same as for the compiler attribute ofAnt'sjavactask. If the value is not set, then the default Eclipse JDT Java compiler willbe used instead of using Ant. There is no default value. If this attribute isset then
setenv.[sh|bat]
should be used to addant.jar
,ant-launcher.jar
andtools.jar
to theCLASSPATH
environment variable. - compilerSourceVM - What JDK version are the source filescompatible with? (Default value:
1.8
) - compilerTargetVM - What JDK version are the generated filescompatible with? (Default value:
1.8
) - development - Is Jasper used in development mode? If true,the frequency at which JSPs are checked for modification may be specified viathe modificationTestInterval parameter.
true
orfalse
,defaulttrue
. - displaySourceFragment - Should a source fragment beincluded in exception messages?
true
orfalse
,defaulttrue
. - dumpSmap - Should the SMAP info for JSR45 debugging bedumped to a file?
true
orfalse
, defaultfalse
.false
if suppressSmap is true. - enablePooling - Determines whether tag handler pooling isenabled. This is a compilation option. It will not alter the behaviour of JSPsthat have already been compiled.
true
orfalse
,defaulttrue
. - engineOptionsClass - Allows specifying the Options classused to configure Jasper. If not present, the default EmbeddedServletOptionswill be used. This option is ignored if running under a SecurityManager.
- errorOnUseBeanInvalidClassAttribute - Should Jasper issuean error when the value of the class attribute in an useBean action is not avalid bean class?
true
orfalse
, defaulttrue
. - fork - Have Ant fork JSP page compiles so they areperformed in a separate JVM from Tomcat?
true
orfalse
, defaulttrue
. - genStringAsCharArray - Should text strings be generated as chararrays, to improve performance in some cases? Default
false
. - ieClassId - Deprecated. Will be removed in Tomact 10.1.The class-id value to be sent to InternetExplorer when using <jsp:plugin> tags. Default
clsid:8AD9C840-044E-11D1-B3E9-00805F499D93
. - javaEncoding - Java file encoding to use for generatingjava source files. Default
UTF8
. - keepgenerated - Should we keep the generated Java sourcecode for each page instead of deleting it?
true
orfalse
, defaulttrue
. - mappedfile - Should we generate static content with oneprint statement per input line, to ease debugging?
true
orfalse
, defaulttrue
. - maxLoadedJsps - The maximum number of JSPs that will beloaded for a web application. If more than this number of JSPs are loaded, theleast recently used JSPs will be unloaded so that the number of JSPs loaded atany one time does not exceed this limit. A value of zero or less indicates nolimit. Default
-1
- jspIdleTimeout - The amount of time in seconds a JSP can beidle before it is unloaded. A value of zero or less indicates never unload.Default
-1
- modificationTestInterval - Causes a JSP (and its dependentfiles) 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 of0 will cause the JSP to be checked on every access. Used in development modeonly. Default is
4
seconds. - recompileOnFail - If a JSP compilation fails should themodificationTestInterval be ignored and the next access trigger a re-compilationattempt? Used in development mode only and is disabled by default as compilationmay be expensive and could lead to excessive resource usage.
- scratchdir - What scratch directory should we use whencompiling JSP pages? Default is the work directory for the current webapplication. This option is ignored if running under a SecurityManager.
- suppressSmap - Should the generation of SMAP info for JSR45debugging be suppressed?
true
orfalse
, defaultfalse
. - trimSpaces - Should template text that consists entirely ofwhitespace be removed from the output (
true
), replaced with asingle space (single
) or left unchanged (false
)?Alternatively, theextended
option will remove leading and trailingwhitespace from template text and collapse sequences of whitespace and newlineswithin the template text to a single new line. Note that if a JSP page or tagfile specifies atrimDirectiveWhitespaces
value oftrue
, that will take precedence over this configuration setting forthat page/tag. Defaultfalse
. - xpoweredBy - Determines whether X-Powered-By responseheader is added by generated servlet.
true
orfalse
,defaultfalse
. - strictQuoteEscaping - When scriptlet expressions are usedfor attribute values, should the rules in JSP.1.6 for the escaping of quotecharacters be strictly applied?
true
orfalse
, defaulttrue
. - quoteAttributeEL - When EL is used in an attribute valueon a JSP page, should the rules for quoting of attributes described in JSP.1.6be applied to the expression?
true
orfalse
, defaulttrue
.
The Java compiler from Eclipse JDT in included as the default compiler. It isan advanced Java compiler which will load all dependencies from the Tomcat classloader, which will help tremendously when compiling on large installations withtens of JARs. On fast servers, this will allow sub-second recompilation cyclesfor even large JSP pages.
Apache Ant, which was used in previous Tomcat releases, can be used insteadof the new compiler by configuring the compiler attribute as explained above.
If you need to change the JSP Servlet settings for an application you canoverride the default configuration by re-defining the JSP Servlet in/WEB-INF/web.xml
. However, this may cause problems if you attemptto deploy the application on another container as the JSP Servlet class maynot be recognised. You can work-around this problem by using the Tomcat specific/WEB-INF/tomcat-web.xml
deployment descriptor. The format isidentical to /WEB-INF/web.xml
. It will override any defaultsettings but not those in /WEB-INF/web.xml
. Since it is Tomcatspecific, it will only be processed when the application is deployed onTomcat.
Known issues
As described inbug 39089, a known JVM issue,bug 6294277, may cause ajava.lang.InternalError: name is too long to represent
exceptionwhen compiling very large JSPs. If this is observed then it may be worked aroundby using one of the following:
- reduce the size of the JSP
- disable SMAP generation and JSR-045 support by setting
suppressSmap
totrue
.
Production Configuration
The main JSP optimization which can be done is precompilation of JSPs.However, this might not be possible (for example, when using thejsp-property-group feature) or practical, in which case the configuration of theJasper servlet becomes critical.
When using Jasper 2 in a production Tomcat server you should consider makingthe following changes from the default configuration.
- development - To disable on access checks for JSPpages compilation set this to
false
. - genStringAsCharArray - To generate slightly more efficientchar arrays, set this to
true
. - modificationTestInterval - If development has to be set to
true
for any reason (such as dynamic generation of JSPs), settingthis to a high value will improve performance a lot. - trimSpaces - To remove unnecessary bytes from the response,consider setting this to
single
orextended
.
Web Application Compilation
Using Ant is the preferred way to compile web applications using JSPC. Notethat when pre-compiling JSPs, SMAP information will only be included in thefinal 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:
<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>
The following command line can be used to run the script(replacing the tokens with the Tomcat base path and the path to the webappwhich should be precompiled):
$ANT_HOME/bin/ant -Dtomcat.home=<$TOMCAT_HOME> -Dwebapp.path=<$WEBAPP_PATH>
Then, the declarations and mappings for the servlets which were generatedduring the precompilation must be added to the web application deploymentdescriptor. Insert the ${webapp.path}/WEB-INF/generated_web.xml
at the right place inside the ${webapp.path}/WEB-INF/web.xml
file.Restart the web application (using the manager) and test it to verify it isrunning fine with precompiled servlets. An appropriate token placed in theweb application deployment descriptor may also be used to automaticallyinsert the generated servlet declarations and mappings using Ant filteringcapabilities. This is actually how all the webapps distributed with Tomcatare automatically compiled as part of the build process.
At the jasper task you can use the option addWebXmlMappings
forautomatic merge the ${webapp.path}/WEB-INF/generated_web.xml
with the current web application deployment descriptor at${webapp.path}/WEB-INF/web.xml
.
When you want to use a specific version of Java for your JSP's, add thejavac compiler task attributes source
and target
withappropriate values. For example, 16
to compile JSPs for Java 16.
For production you may wish to disable debug info withdebug="off"
.
When you don't want to stop the JSP generation at first JSP syntax error, usefailOnError="false"
and withshowSuccess="true"
all successful JSP to Javageneration are printed out. Sometimes it is very helpful, when you cleanup thegenerate java source files at ${webapp.path}/WEB-INF/src
and the compile JSP servlet classes at${webapp.path}/WEB-INF/classes/org/apache/jsp
.
Hints:
- When you switch to another Tomcat release, then regenerate and recompileyour JSP's with the new Tomcat version.
- Use java system property at server runtime to disable PageContext pooling
org.apache.jasper.runtime.JspFactoryImpl.USE_POOL=false
.and limit the buffering withorg.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true
. Notethat changing from the defaults may affect performance, but it will varydepending on the application.
Optimisation
There are a number of extension points provided within Jasper that enable theuser to optimise the behaviour for their environment.
The first of these extension points is the tag plug-in mechanism. This allowsalternative implementations of tag handlers to be provided for a web applicationto use. Tag plug-ins are registered via a tagPlugins.xml
filelocated under WEB-INF
. A sample plug-in for the JSTL is includedwith Jasper.
The second extension point is the Expression Language interpreter. Alternativeinterpreters may be configured through the ServletContext
. See theELInterpreterFactory
javadoc for details of how to configure analternative EL interpreter. A alternative interpreter primarily targeting tagsettings is provided atorg.apache.jasper.optimizations.ELInterpreterTagSetters
. See thejavadoc for details of the optimisations and the impact they have onspecification compliance.
An extension point is also provided for coercion of String values to Enums. Itis provided atorg.apache.jasper.optimizations.StringInterpreterEnum
. See thejavadoc for details of the optimisations and the impact they have onspecification compliance.