Fork me on GitHub

The Default Classpath

The Surefire plugin builds the test classpath at runtime in the following order:

  1. The test-classes directory
  2. The classes JAR file or directory
  3. The project dependencies (with all scopes)
  4. Additional classpath elements

    Notice that loading JAR file is preferable over the output classes directory in the maven-failsafe-plugin. This behavior can be changed by configuration parameter classesDirectory.

Additional Classpath Elements

If you need to put more stuff in your classpath when Failsafe executes (e.g some funky resources or a container specific JAR), we normally recommend you add it to your classpath as a regular project dependency (with scope test). Consider deploying shared JARs to a private remote repository for your organization.

In case this leads to dependency conflicts usually separating the test classes from the actual test execution into separate Maven modules is the recommended approach then.

But, if you must, you can use the additionalClasspathElements element to add custom resources/JARs to your test classpath at runtime (without affecting the test classpath used for compilation). The items will be treated as absolute file system paths, so you may want use ${basedir} or another property combined with a relative path. Note that additional classpath elements are added to the end of the classpath, so you cannot use these to override project dependencies or resources.

<project>
  [...]
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-failsafe-plugin</artifactId>
        <version>3.5.2</version>
        <configuration>
          <additionalClasspathElements>
            <additionalClasspathElement>path/to/additional/resources</additionalClasspathElement>
            <additionalClasspathElement>path/to/additional/jar</additionalClasspathElement>
            <additionalClasspathElement>path/to/csv/jar1, path/to/csv/jar2</additionalClasspathElement>
          </additionalClasspathElements>
        </configuration>
      </plugin>
    </plugins>
  </build>
  [...]
</project>

Since version 3.2.0 the additionalClasspathDependencies parameter can be used to add arbitrary dependencies to your test execution classpath via their regular Maven coordinates. Those are resolved from the repository like regular Maven project dependencies and afterwards added as additional classpath elements to the end of the classpath, so you cannot use these to override project dependencies or resources (except those which are filtered with classpathDependencyExclude). All artifacts of scope compile and runtime scope from the dependency tree rooted in the given dependency are added. The parametrization works like for regular Maven dependencies in a POM. Exlusions are supported as well. Neither the dependency management section from the underlying POM is used nor are the conflicts among the different dependency trees (from the project dependencies or from the additional dependencies) automatically resolved. Conflicts lead to warnings, though, which help you clean up the classpath manually. Only external dependencies (outside the current Maven reactor) are supported.

<project>
  [...]
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-failsafe-plugin</artifactId>
        <version>3.5.2</version>
        <configuration>
          <additionalClasspathDependencies>
            <additionalClasspathDependency>
              <groupId>myGroupId</groupId>
              <artifactId>myArtifactId</artfactId>
              <version>1.0.0</version>
              <exclusions>
                <exclusion>
                  <groupId>org.apache.maven</groupId>
                  <artifactId>maven-core</artifactId>
                </exclusion>
              </exclusions>
            </additionalClasspathDependency>
          </additionalClasspathDependencies>
        </configuration>
      </plugin>
    </plugins>
  </build>
  [...]
</project>

Removing Dependency Classpath Elements

Dependencies can be removed from the test classpath using the parameters classpathDependencyExcludes and classpathDependencyScopeExclude. A list of specific dependencies can be removed from the classpath by specifying the groupId:artifactId to be removed. Details of the pattern matching mechanism are outlined in the goal parameter description for classpathDependencyScopeExcludes. It is important to note that this filtering is only applied to the effective project dependencies (this includes transitive project dependencies).

<project>
  [...]
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-failsafe-plugin</artifactId>
        <version>3.5.2</version>
        <configuration>
          <classpathDependencyExcludes>
            <classpathDependencyExclude>org.apache.commons:commons-email</classpathDependencyExclude>
          </classpathDependencyExcludes>
        </configuration>
      </plugin>
    </plugins>
  </build>
  [...]
</project>

Dependencies under a certain scope can be removed from the classpath using classpathDependencyScopeExclude. The valid values for the dependency scope exclude are defined by org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter.

  • compile - system, provided, compile
  • runtime - compile, runtime
  • test - system, provided, compile, runtime, test
    <project>
      [...]
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>3.5.2</version>
            <configuration>
              <classpathDependencyScopeExclude>runtime</classpathDependencyScopeExclude>
            </configuration>
          </plugin>
        </plugins>
      </build>
      [...]
    </project>