Maven resources plugin filtering not working

Following is the Note from the official reference document: (refer to https://docs.spring.io/spring-boot/docs/2.3.2.RELEASE/maven-plugin/reference/html/)

Note that, since the application.properties and application.yml files accept Spring style placeholders (${…​}), the Maven filtering is changed to use @..@ placeholders. (You can override that by setting a Maven property called resource.delimiter.)


I had similar issue when using copy-resources goal of maven properties plugin. The resources were copied but placeholders were not replaced. For me this was because of silly mistake - I copied the resources in eariler maven phase (validate) and I included placeholders properties file in later phase (initialize)... so the properties were not yet available.

I changed the phase of including the properties to validate and inclusion of placeholders to initialize and all works fine.

My working config is following:

Inclusion of properties file in validate:

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>properties-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals>
                            <goal>read-project-properties</goal>
                        </goals>
                        <configuration>
                            <files>
                                <file>${project.basedir}/path/to/placeholders.properties</file>
                            </files>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

Copying resources in initialize:

   <plugin>
        <artifactId>maven-resources-plugin</artifactId>
        <executions>
            <execution>
                <id>copy-resources</id>
                <!-- here the phase you need -->
                <phase>initialize</phase>
                <goals>
                    <goal>copy-resources</goal>
                </goals>
                <configuration>
                    <encoding>UTF-8</encoding>
                    <outputDirectory>${project.build.directory}/classes</outputDirectory>
                    <resources>
                        <resource>
                            <directory>${basedir}/path/to/directory/with/resources/to/copy</directory>
                            <filtering>true</filtering>
                        </resource>
                    </resources>
                </configuration>
            </execution>

The problem is that you're configuring main resources instead of test resources; the main resources are configured with the resource element, whereas the test resources are configured with the testResource element. With the current configuration, the files under src/test/resources would be treated as filtered main resources, and the actual test resources would be unfiltered. This is why the copied properties file under target/test-classes is not filtered.

What you're looking for is:

<testResources>
  <testResource>
    <directory>src/test/resources</directory>
    <filtering>true</filtering>
  </testResource>
</testResources>

With this, the files under src/test/resources will be treated as filtered test resources, and the main resources will be left untouched.