Thursday, February 23, 2012

Maven substitution and Freemarker template

If you're using Freemarker template in Maven projects, double check to be sure your templates are not alerted by Maven filtering during build process.

During Maven build, the Maven filtering process will scan all resources for property references surrounded by ${ and }. When it finds these references it will replace them with the appropriate value. If any Freemarker templates are in Maven resource directory (e.g. src/main/resources), and contains Freemarker variable names (surrounded by ${ and } as well) that are also maven property names, then these references will be replaced with maven property values.

An example is shown in below

<tr>
  <td class="label">Name:</td>
  <td>${name}</td>
</tr>

Where the ${name} variable is meant to a Freemarker variable name and should be replaced during application runtime using model values, however, during Maven build, it is replaced to the Maven project name and the final package file will have the template file with the variable substituted, as shown in below.

<tr>
  <td class="label">Name:</td>
  <td>My Maven project</td>
</tr>

Simple way to fix this is to use a different variable name that maven doesn't aware, or a better way is to disable the maven filtering for all Freemarker template files in the pom file. In order to do so, you need to declare two mutually exclusive resource sets, the first resource set execludes Freemark templates from the filtering, and the other resource set copies Freemark templates unaltered, as shown in below.

<resources>
  <resource>
    <directory>src/main/resources</directory>
    <filtering>true</filtering>
    <excludes>
      <exclude>**/*.ftl</exclude>
    </excludes>
  </resource>
  <resource>
    <directory>src/main/resources</directory>
    <filtering>false</filtering>
    <includes>
      <include>**/*.ftl</include>
    </includes>
  </resource>
</resources>
    

1 comment: