Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to precompile .jspf files with jasper2 in ant

.jspf files are "Java server fragments" -- jsp that is intended only for inclusion () in other .jsp files.

Precompiling all .jsp files is very handy because it exposes syntax errors, missing imports, java code errors, etc. at build time rather than run time. We've all struggled with typos in .jsp not showing up until we view a page. I'm putting an automatic task into ant to precompile all my JSP files. (see http://tomcat.apache.org/tomcat-7.0-doc/jasper-howto.html#Web_Application_Compilation).

Tomcat's jsp compiler jasper2 has built in it an assumption that all jsp files have the '.jsp' file extension. This goes against current recommendations to use .jspf file extensions when appropriate.

THE QUESTION: how to code an ant task that will invoke jasper2 (aka jspC) to precompile all .jsp files, including .jspf files?

like image 958
TSnyder Avatar asked May 15 '13 01:05

TSnyder


People also ask

How do I Precompile a JSP file?

Add jsp_precompile as a request parameter and send a request to the JSP file. This will make the jsp pre-compile. Why it is mentioned as pre compile instead of compilation is that, the request is not served. That is, the JSP will not be executed and the request will not be serviced.

Can we configure or override Tomcat Jasper?

It will override any default settings but not those in /WEB-INF/web. xml . Since it is Tomcat specific, it will only be processed when the application is deployed on Tomcat.

What is Jasper in JSP?

Jasper is Tomcat's JSP engine, which implements the JSP specification. It compiles JSP files to Java code. Here is the Wikipedia article. Older versions of Tomcat used to require JDK in order to compile JSP files. This is no longer necessary, as Jasper can do this job.

What is Tomcat Jasper used for?

Jasper is Tomcat's JSP Engine. Jasper parses JSP files to compile them into Java code as servlets (that can be handled by Catalina). At runtime, Jasper detects changes to JSP files and recompiles them. As of version 5, Tomcat uses Jasper 2, which is an implementation of the Sun Microsystems' JSP 2.0 specification.


1 Answers

-- THE ANSWER

(see discussion below for correction to the other answers related to this)

Use ant helper tasks to build a textual list of .jspf files to compile and pass that to the jasper2 task in the jspfiles attribute. As follows:

<target name="precompilejsp">

    <taskdef name="jasper2" classname="org.apache.jasper.JspC"> 
      <classpath refid="compile.classpath"/>
    </taskdef>

<!-- THIS is the guts of the solution -->
    <!-- Jasper2 refuses to precompile .jspf unless we list them specifically. Boo hoo. -->
    <fileset id="jspffiles" dir="${appdir.build}"> 
      <include name="**/*.jspf"/>
      <include name="**/*.jsp"/> 
    </fileset>

<!-- This turns the set into a textual comma-separated list -->
    <pathconvert targetos="unix" pathsep="," property="app.jspflist" refid="jspffiles"/>
    <!-- echo message="Jspf files are: ${app.jspflist}"/ -->

<!-- Do the precompilation by invoking Jasper2 -->
    <jasper2 
             validateXml="false" 
             uriroot="${appdir.build}"
             jspfiles="${app.jspflist}"
             webXmlFragment="${precompile_tmp_dir}/generated_web.xml" 
             outputDir="${precompile_tmp_dir}">
    </jasper2>

    <!-- Now compile those .java sources to generate any error messages. -->
   <mkdir    dir="${precompile_tmp_dir}/WEB-INF/classes"/>
   <javac srcdir="${precompile_tmp_dir}"
          destdir="${precompile_tmp_dir}/WEB-INF/classes"
            debug="${compile.debug}"
      deprecation="${compile.deprecation}"
         optimize="${compile.optimize}"
        includeantruntime="false">
        <classpath refid="compile.classpath"/>
    </javac>

</target> 

--- DISCUSSION

It has been stated in the referenced What is .jspf file extension? How to compile it? (and elsewhere on the web) that .jspf files are not generally to be compiled on their own, and that they are textually included via a <jsp:include> references from other files. That claim and reasoning are wrong. The Tomcat Jasper .jsp compiler does in fact compile .jspf stand-alone during the normal display-time processing of .jsp and related .jspf files. This can be trivially seen by inspecting /usr/share/tomcat/work/Catalina/localhost/org/youdomain/yourpath/includefile_jspf.java. This .java file is generated as stand-alone code for your .jspf file. Bottom line is that <jsp:include> does not work like C's #include(), rather it includes at runtime the output of the jspf file in the output of the including-file, rather than including the source of the jspf file into the source of the .jsp file as C would have.

The claim in that referenced answer that WEB-INF/somejsp.jsp files cannot be viewed by end users is also false. It is common to put ALL .jsp files in WEB-INF and to reference them in Servlet code gateways mapped in web.xml or other servlet request forwarding mechanisms:

  RequestDispatcher dispatcher = servctxThis.getRequestDispatcher( "/WEB-INF/JSP/thewholepage.jsp" );
  dispatcher.forward(request, response);

So, to be specific, .jsp files in /WEB-INF cannot be directly viewed by end users, but they can be forwarded-to by any servlet OR other JSP file, and do often comprise an entire web response -- <HTML> ... </HTML>. (.jspf, on the other hand, often contain a snippet or fragment of HTML response --- <DIV>header-content</DIV>, for example.

like image 172
TSnyder Avatar answered Oct 16 '22 10:10

TSnyder