Maven: The Complete Reference
9.3. Resource Filtering

You can use Maven to perform variable replacement on project resources. When resource filtering is activated, Maven will scan resources for property references surrounded by ${ and }. When it finds these references it will replace them with the appropriate value in much the same way the properties defined in the previous section can be referenced from a POM. This feature is especially helpful when you need to parameterize a build with different configuration values depending on the target deployment platform.
Often a .properties file or an XML document in src/main/resources will contain a reference to an external resource such as a database or a network location which needs to be configured differently depending on the target deployment environment. For example, a system which reads data from a database has an XML document which contains the JDBC URL along with credentials for the database. If you need to use a different database in development and a different database in production. You can either use a technology like JNDI to externalize the configuration from the application in an application server, or you can create a build which knows how to replace variables with different values depending on the target platform.
Using Maven resource filtering you can reference Maven properties and
then use Maven profiles to define different configuration values for
different target deployment environments. To illustrate this feature,
assume that you have a project which uses the Spring Framework to
configure a BasicDataSource from the
Commons DBCP project. Your project may
contain a file in src/main/resources named applicationContext.xml
which contains the XML listed in Referencing Maven Properties from a Resource.
Referencing Maven Properties from a Resource.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="someDao" class="com.example.SomeDao">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
</beans>
Your program would read this file at runtime, and your build is going
to replace the references to properties like jdbc.url and
jdbc.username with the values you defined in your pom.xml. Resource
filtering is disabled by default to prevent any unintentional resource
filtering. To turn on resource filtering, you need to use the
resources child element of the build element in a
POM. Defining Variables and Activating Resource Filtering shows a POM which defines the variables
referenced in Referencing Maven Properties from a Resource and which activates resource
filtering for every resource under src/main/resources.
Defining Variables and Activating Resource Filtering.
<project>
...
<properties>
<jdbc.driverClassName>
com.mysql.jdbc.Driver</jdbc.driverClassName>
<jdbc.url>jdbc:mysql://localhost:3306/development_db</jdbc.url>
<jdbc.username>dev_user</jdbc.username>
<jdbc.password>s3cr3tw0rd</jdbc.password>
</properties>
...
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
...
<profiles>
<profile>
<id>production</id>
<properties>
<jdbc.driverClassName>oracle.jdbc.driver.OracleDriver</jdbc.driverClassName>
<jdbc.url>jdbc:oracle:thin:@proddb01:1521:PROD</jdbc.url>
<jdbc.username>prod_user</jdbc.username>
<jdbc.password>s00p3rs3cr3t</jdbc.password>
</properties>
</profile>
</profiles>
</project>
The four variables are defined in the properties element, and
resource filtering is activated for resources under
src/main/resources. Resource filtering is deactivated by default,
and to activate it you must explicitly set filtering to true for
the resources stored in your project. Filtering is deactivated by
default to prevent accidental, unintentional filtering during your
build. If you build a project with the resource from
Referencing Maven Properties from a Resource and the POM from Defining Variables and Activating Resource Filtering and if you
list the contents of the resource in target/classes, you should see
that it contains the filtered resource:
$ mvn install
...
$ cat target/classes/applicationContext.xml
...
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/development_db"/>
<property name="username" value="dev_user"/>
<property name="password" value="s3cr3tw0rd"/>
</bean>
...
The POM in Defining Variables and Activating Resource Filtering also defines a production profile under
the profiles/profile element which overrides the default properties
with values that would be appropriate for a production environment. In
this particular POM, the default values for the database connection
are for a local MySQL database installed on a developer’s
machine. When the project is built with the production profile
activated, Maven will configure the system to connect to a production
Oracle database using a different driver class, URL, username, and
password. If you build a project with the resource from
Referencing Maven Properties from a Resource and the POM from Defining Variables and Activating Resource Filtering with the
production profile activated and if you list the contents of the
resource in target/classes, you should see that it contains the
filtered resource with production values:
$ mvn -Pproduction install
...
$ cat target/classes/applicationContext.xml
...
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName"
value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@proddb01:1521:PROD"/>
<property name="username" value="prod_user"/>
<property name="password" value="s00p3rs3cr3t"/>
</bean>
...
