Search code examples
javaspringmavenspring-bootmaven-failsafe-plugin

Change working directory for Maven failsafe pre-integration-test to find Spring configuration


We have a multi module Maven project with multiple executable projects inside.

The directory structure looks similar to this:

parent
+- module1
+-- src/main/resources/application.yml
+-- config/bootstrap.yml
+-- config/application-dev.yml
+-- config/application-prod.yml
+-- pom.xml
+- pom.xml

where application.yml are packaged default values that are not environment specific and all files in the config folder belongs to external configuration needed only for local development which is not part of the WAR file.

Now if I start the application or tests from the IDE it works as expected. Also, if I run Maven builds in module1 folder. However, if I try to build the parent project, the bootstrap.yml is not found which fails the build during the pre-integration-test phase.

I discovered that the working directory is set to the parent folder instead of module1 which seems to be the problem as Spring looks in . and ./config. If I duplicate the config folder to root, it works in all cases.

Is there any way to tell Maven failsafe to set the working directory to the module folder during pre-integration-test phase where the Spring Context looks for the configuration?

parent/pom.xml:

<project ...>
    <properties>
        <maven.version>3.0.0</maven.version>
        <maven-surefire-plugin.version>2.18.1</maven-surefire-plugin.version>
        <maven-failsafe-plugin.version>2.20.1</maven-failsafe-plugin.version>
    </properties>
    <modules>
        <module>module1</module>
    </modules>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-failsafe-plugin</artifactId>
                    <version>${maven-failsafe-plugin.version}</version>
                    <configuration>
                        <runOrder>alphabetical</runOrder>
                        <includes>
                            <include>**/*IntTest.java</include>
                        </includes>
                        <skipTests>${skipTests}</skipTests>
                    </configuration>
                    <executions>
                        <execution>
                            <goals>
                                <goal>integration-test</goal>
                                <goal>verify</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

parent/module1/pom.xml:

<project>
    <parent>
        ...
    </parent>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
            </plugin>
            </plugins>
        </plugins>
    </build>
</project>

Solution

  • Ok, for some reason both <environmentVariables> and <systemProperties> in the <config> block of maven-failsafe-plugin does not work in combination with spring-boot-maven-plugin.

    It appears that spring-boot plugin is responsible to create the (forked) JVM in the pre-integration-test phase because of this snippet:

            <execution>
                <id>pre-integration-test</id>
                <goals>
                    <goal>start</goal>
                </goals>
            </execution>
    

    I solved it by configuring the spring-boot-maven-plugin instead:

            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <workingDirectory>${basedir}</workingDirectory>
    

    According to documentation ${basedir} should be the default but maybe it doesn't work with Maven multi-module projects.