Monday, September 14, 2009

Precompiling JSPs with Maven - Part 2

If you use war dependencies for building your web applications the approach described in part 1 will not work for your application because the JSPC-Plugin by default works on your local JSP files and is executed during the lifecycle phase "process-classes".

Here is how to deal with this added requirement.


Moreover if you use tag files in your JSPs (especially if the Tag pages come from the included web application) the JSP parser will fail when trying to compile the  JSP files because it needs access to the sources of all JSP pages referenced.

The solution to this problems exploits the fact that the war plugin checks for modifications before every step it takes.

The steps for the solution described here are acutally quite simple:
  1. Configure an extra Execution of the WAR-Plugin to run during the lifecycle phase "process-classes" to exectue the goal "exploded".
  2. Run the jspc plugin during the same execution but after the war plugin has run but configure it to operate on the exploded war archive.
  3. Run the war plugin again with goal "war" during lifecycle phase "package". 
Please see the next code snippet for the solution described above:
<plugin> 
  <groupId>org.codehaus.mojo.jspc</groupId> 
  <artifactId>jspc-maven-plugin</artifactId> 
  <executions> 
    <execution> 
      <id>precompileJsps</id> 
      <goals> 
        <goal>compile</goal> 
      </goals> 
      <phase>package</phase> 
      <configuration> 
        <sources> 
          <directory>${basedir}/target/${project.build.finalName}</directory> 
          <includes> 
            <include>**/*.jspx</include> 
          </includes> 
        </sources> 
        <source>1.5</source> 
        <target>1.5</target> 
        <verbose>1</verbose> 
        <inputWebXml>${basedir}/target/${project.build.finalName}/WEB-INF/web.xml</inputWebXml> 
      </configuration> 
    </execution> 
  </executions> 
  <dependencies> 
    <!-- Please see Part 1 for jspc dependencies -->
  </dependencies> 
</plugin> 
The configuration of the war plugin looks like this:
<plugin> 
  <artifactId>maven-war-plugin</artifactId> 
  <executions> 
    <execution> 
      <id>precompileJsps</id> 
      <goals> 
        <goal>exploded</goal> 
      </goals> 
      <phase>process-classes</phase> 
      <configuration> 
        <warSourceDirectory>${basedir}/WebContent</warSourceDirectory> 
        <overlays> 
          <overlay> 
            <groupId>com.acme</groupId> 
            <artifactId>base-webapp</artifactId> 
          </overlay> 
        </overlays> 
      </configuration> 
    </execution> 
    <execution> 
      <goals> 
        <goal>war</goal> 
      </goals> 
      <configuration> 
        <warSourceDirectory>${basedir}/target/${project.build.finalName}</warSourceDirectory> 
        <overlays> 
          <overlay> 
            <groupId>com.acme</groupId> 
            <artifactId>base-webapp</artifactId> 
          </overlay> 
        </overlays> 
      </configuration> 
    </execution> 
  </executions> 
</plugin> 
Important: The war plugin has to be configured before the war plugin in the POM because Maven executes the plugins within an execution in the order they are declared in the POM.

An that's all there is to precomipling JSPs in a multi project implementation using war dependencies.

No comments:

Post a Comment