Fork me on GitHub

Configuring endorsed libraries in unit tests (Java <= 8)

In some cases, you need to run your unit tests with certain APIs at a different version level than what is provided by the JRE, either because you want to ensure that your code is compatible with older versions of these APIs or because the versions of the APIs included in the JRE are not the most recent ones, but your code expects the latest versions.

In a Maven build this is typically achieved by using maven-dependency-plugin to copy these libraries to a folder under target/ and configuring maven-surefire-plugin to add -Djava.endorsed.dirs=... (with the directory containing the JARs) or -Xbootclasspath/p:... (with the list of individual JARs) to the command line of the JVM that executes the tests.

Copying the JARs to the project build directory is an extra step that should not be necessary, considering that the JARs are already in the local Maven repository. To avoid this extra step, one needs to compute the paths to the artifacts in the local repository and pass the list of these paths to the -Xbootclasspath/p:... JVM argument.

This can easily be achieved with the help of the alta:generate-properties goal:

<plugin>
    <groupId>com.github.veithen.alta</groupId>
    <artifactId>alta-maven-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>generate-properties</goal>
            </goals>
            <configuration>
                <name>surefire.bootclasspath</name>
                <value>%file%</value>
                <separator>${path.separator}</separator>
                <artifactSet>
                    <artifacts>
                        <artifact>
                            <groupId>xerces</groupId>
                            <artifactId>xmlParserAPIs</artifactId>
                            <version>2.6.2</version>
                        </artifact>
                        <artifact>
                            <groupId>org.apache.axis</groupId>
                            <artifactId>axis-saaj</artifactId>
                            <version>1.4</version>
                        </artifact>
                    </artifacts>
                </artifactSet>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
        <argLine>-Xbootclasspath/p:${surefire.bootclasspath}</argLine>
    </configuration>
</plugin>

Note: This configuration uses surefire.bootclasspath as property name. You should avoid using bootclasspath here because that property is used as a default value for the bootclasspath parameter by maven-javadoc-plugin.