Rajendra's Ramblings
Where Horizons Meet
Maven: filtering resources conditionally while packaging
Posted by on February 22, 2012
When building artifacts using Maven, some times we require to filter resources (replace reference variables in the resource files with their actual values either from properties or env. variables). The resources element under build is meant for this task. The resources configuration gets triggered before compile taget(Refer to Maven life cycle : Lifecycle Reference).
Consider the below project structure (as an example):
`-- src
`-- main
|-- java
| `-- com
| `-- example
| `-- projects
| `-- SampleAction.java
|-- resources
| `-- spring-config.xml
| `-- version.properties
| `-- config.properties
| `-- spring-beans.xml
`-- webapp
|-- WEB-INF
| `-- web.xml
|-- index.jsp
`-- jsp
`-- websource.jsp
Below is the maven snippet that translates the referenced properties :
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
filtering=true, enables the resolution of the variables above. Now if you look at the resource files you can see all variables are translated to their actual environment/property value. But I don’t want to replace the values in all the files.
I only want specific set of files to obey the translation(filtered) and the rest not to honor the translation rules
For Example: I don’t want spring-config.xml’s & config.properties environment references to be translated as they change from environment to environment. However, I want my version.properties to be translated to contain the project artifact details, build time etc.. along with and spring-beans.xml.
The below resource configuration helps me achieve this.
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/version.properties</include>
<include>**/spring-beans.xml</include>
</includes>
<excludes>
<exclude>**/spring-config.xml</exclude>
<exclude>**/config.properties</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>**/spring-config.xml</include>
<include>**/config.properties</include>
</includes>
<excludes>
<exclude>**/version.properties</exclude>
<exclude>**/spring-beans.xml</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
The “resources” configuration is used to process your resources directory and copy these resources to the target resources directory.
The first resource config filters (variables are replaced with actual values) the ‘version.properties’ and ‘spring-beans.xml’ and copies to the output directory.
So why do I have the second ‘resource’ config? Try removing the 2nd resource config and check. You will find only the 2 files referred in the config are copied and the other two are not copied. If you add the 2nd resource config, it processes only those it is configured to process (includes/excludes). The ‘filtering=false’ hints maven to not translate the properties of the included files and copy them as is to the target directory. The files in the excludes (spring-beans.xml & version.properties) are excluded from processing(including the copying task).
You can add as many ‘resource’ configurations as per your requirements and they are processed sequentially in the order they are listed.
The <includes> filters gets the list of files that match the criteria and on that list the <excludes> filter is applied.
Refer Resources plugin for more details : Resources