Search code examples
mavenmaven-3pom.xmlmaven-profilesmaven-resources-plugin

Maven resource filtering - Explicitly specify which files require property injection


Does the Maven resources plugin allow a flexible way to exclude certain files during the injection of Maven profile properties?

  • I don't want to exclude the files from assembly, just from the injection phase.

The project I'm working on defines unique Maven Profiles (and corresponding properties) in Settings.xml for each deployment environment. When the project is built the following steps occur

  • The projects POM defines the resources folder as the target to apply resource filtering
  • The resources folder contains .XML and .PROPERTIES files
  • During mvn:deploy Maven injects Profile properties into the .PROPERTIES file as expected
  • Maven also injects Profile properties into .XML files. This is not desired behavior (these files contain placeholders which allow the project to flexible inject values during deploy of the application)

The resource plugin provides configuration options to define include and exclude options however choosing the exclude option will also exclude the specified file from the assembly folder which is not desired.

Is it possibly to tell Maven which files should have placeholders replaced?


Solution

  • You are probably using the filters mechanism, for which you can decide whether to apply it to a certain folder and which filter should be applied to that folder.

    Given the following sample POM:

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.sample</groupId>
        <artifactId>resources-example</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <build>
            <filters>
                <filter>src/main/filters/filter.properties</filter>
            </filters>
    
            <resources>
                <!-- configuring an additional resources folder: conf -->
                <resource>
                    <directory>${project.basedir}/src/main/conf</directory>
                    <filtering>true</filtering>
                    <excludes>
                        <exclude>*.txt</exclude>
                    </excludes>
                    <includes>
                        <include>*.properties</include>
                    </includes>
                    <targetPath>${project.basedir}/target</targetPath>
                </resource>
            </resources>
        </build>
    </project>
    

    Note the filters section within the build section. Here we are telling Maven where how filter is, providing placeholders replacement.

    Note then the <filtering>true</filtering> addition to a new resource configured afterwards and related includes/excludes patterns. As such, Maven will filter only the *.properties files of this folder.

    Now, src/main/conf can contain a conf.properties file with the following content:

    ## add some properties here
    [email protected]@
    property.example2=${property.value2}
    

    (Note the ant and maven style placeholders.)

    While the src/main/filters (you need to create this folder) contains the filter.properties file with the following content:

    property.value1=filtered-value1
    property.value2=filtered-value2
    

    Running the build you will get the conf.properties file in the target directory with the following content:

    property.example=filtered-value1
    property.example2=filtered-value2
    

    Now, if your filter (file name) is a property injected by a profile, you can then inject different filters depending on the environment and only targeting certain files.