Maven has some really great features. One of them is filtered resources.
Basically, if you use Maven for some time, I’m sure you know what by default everything you put in src/main/resources
will be added to the classpath in the resulting artifact (e.g. in the WEB-INF/classes
for a *.war archive.) Putting
resources in this location is a common way of adding Java properties file to your project.
Now what is interesting: you can use Maven variables in those resource files and they can be swapped into final value
during the process-resource
phase. You just need to tell Maven that it is not a “regular” resource and that it
should be filtered.
As an example: assume you have a following properties file:
src/main/resources/application.properties
app.version = ${version}
And you add the following section to your pom.xml file:
pom.xml
<project>
<build>
...
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>application.properties</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
<project>
During the prepare-resources
phase the application.properties
file will be filtered by Maven. The ${...}
placeholders will be filled with proper values and the resulting application.properties
will be produced and placed
somewhere in the target directory. Its content will be something like:
app.version = 0.1.1-SNAPSHOT
You can use variables available out-of-the-box in Maven or some additional ones coming e.g. from the Maven plugins
or your own defined in the <properties>
pom.xml element. It’s pretty neat if you combine it with
Maven Build Number plugin which can add your revision or some custom made build number and save it to your runtime
accessible property file.
As a side note, if you define the exact files / directories you want to be filtered and want to treat the rest of the
files as regular ones (not filtered) you should instruct Maven to do so. It seems that if you define at least one
<resource>
element, the default values doesn’t apply anymore. Something like this should do the work:
<project>
<build>
...
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>application.properties</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
<project>
You can see an example of how I used it with Build Number plugin here.