(Pre)-compiling JSP for Tomcat with Jasper


When working on a project I like to precompile my JSPs just to test if haven’t made any (syntax) errors or forgot any resources, without having to deploy them on the appserver and testing them one by one.
In a project we are working using Tomcat we use Ant to build the application and package it in war, which is subsequently deployed on the Tomcat server.
This ant build copies all necessary resources to a build directory and starts compilition and war building from there.
I added an extra target to precompile the JSP as follows following the instructions found here.

<target name="jspc" depends="init,copy-and-filter-web-content,copy-meta,make-lib-dir">
  <taskdef classname="org.apache.jasper.JspC" name="jasper2">
    <classpath id="jspc.classpath">
      <pathelement location="${java.home}/../lib/tools.jar" />
      <fileset dir="${env.CATALINA_HOME}/bin">
        <include name="*.jar" />
      <fileset dir="${env.CATALINA_HOME}/server/lib">
        <include name="*.jar" />
      <fileset dir="${env.CATALINA_HOME}/common/lib">
        <include name="*.jar" />
  <jasper2 validateXml="false"
            outputDir="${build.dir.precompiledJSP}" />

In this case I do not deploy the compiled JSPs on the server, I just compile them to test them. So the outputDir is just there for temporary storage.

If I for example put the following line in my JSP:

   <html:img page="/img/struts-power.gif" alt="Powered by Struts">

The build will fail with the following error:

BUILD FAILED: C:developmentPROJECTSAmisHoursbuild.xml:85: org.apache.jasper.JasperException:
file:C:/development/PROJECTS/AmisHours/build/web/index.jsp(38,0) According to TLD, tag html:img must be empty, but is not

Which is easily repaired

   <html:img page="/img/struts-power.gif" alt="Powered by Struts"/>

If you follow the instructions in the document mentioned above, you can also deploy the compiled JSP to the tomcat.
But I think the solution with mapping the individual jsp patterns to classes in the web.xml might be somewhat confusing.


About Author


  1. In a previous project I precompiled the JSPs, obfuscated the resulting class files, and packaged them into the webapp.
    This required that I copy and paste and modify the JspServlet class from the tomcat source code and lightly modify it – mostly stripping out unnecessary stuff.
    Then I did a *.jsp mapping in web.xml to my new JspServlet, included jsp-runtime.jar in my webapp (so that I did not get version inconsistencies when deploying on newer versions of tomcat)
    and voila!
    No precompilation stage, the webapp is fast right from startup, and no JSP source code in the delivered WAR file.