Maven Failsafe: NoClassDefFoundError for integration tests
Asked Answered
C

2

7

Setup: Kotlin integration tests in a spring boot application.

Tests work fine when I run them with IntelliJ. When I try to run the integration tests with maven, though:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-failsafe-plugin:2.19.1:integration-test (default) on project myapp: Execution default of goal org.apache.maven.plugins:maven-failsafe-plugin:2.19.1:integration-test failed: There was an error in the forked process
[ERROR] java.lang.NoClassDefFoundError: ch/cypherk/myapp/service/CustomerService
[ERROR]         at java.base/java.lang.Class.getDeclaredConstructors0(Native Method)
[ERROR]         at java.base/java.lang.Class.privateGetDeclaredConstructors(Class.java:3138)
[ERROR]         at java.base/java.lang.Class.getConstructor0(Class.java:3343)
[ERROR]         at java.base/java.lang.Class.getConstructor(Class.java:2152)
[ERROR]         at org.apache.maven.surefire.junit.PojoAndJUnit3Checker.isPojoTest(PojoAndJUnit3Checker.java:51)
...

which is very annoying since I kind of need bamboo to run the darn things.

The CustomerService is an interface and yes, it is compiled, there's a corresponding .class file in maven's ./target directory and IntelliJ is set up to use the same.

Can't quite figure out why this is failing and would appreciate some help with the plugin.

Relavant excerpt from the pom.xml:

<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.22.0</version>
    <configuration>
        <!-- doesn't make a difference if `true` or `false`-->
        <useSystemClassLoader>false</useSystemClassLoader>
    </configuration>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>2.19.1</version>
    <executions>
        <execution>
            <goals>
                <goal>integration-test</goal>
                <goal>verify</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <includes>
            <include>**/*IT*</include>
        </includes>
        <excludes>
            <exclude>**/ui/*</exclude>
        </excludes>
        <trimStackTrace>false</trimStackTrace>
    </configuration>
</plugin>

Full pom.xml: http://freetexthost.com/dbghyawijj

Full log of the failing integration test step: http://freetexthost.com/gbsmd3mwm2

Corot answered 10/4, 2019 at 9:52 Comment(4)
First, try using the same version of the surefire and failsafe plugins. They are closely related. Not sure it will fix anything, but IMO consistency is the first step.Theran
Also, the <useSystemClassLoader> attribute was added to the Surefire config, but it's Failsafe that's having the problem.Theran
For Spring Boot see https://mcmap.net/q/636040/-maven-failsafe-fails-with-java-lang-noclassdeffounderror and github.com/spring-projects/spring-boot/issues/6254Attainment
Are you using jmockit?Faddish
D
7

Faced the same problem, sovled it by adding target/classes as additional classpath elements. It feels a little bit dirty but works:

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-failsafe-plugin</artifactId>
        <version>2.22.0</version>
        <configuration>
          <additionalClasspathElements>
            <additionalClasspathElement>${basedir}/target/classes</additionalClasspathElement>
          </additionalClasspathElements>
        </configuration>
      </plugin>
Diskson answered 8/10, 2021 at 11:50 Comment(1)
or you can use <classesDirectory>${project.build.outputDirectory}</classesDirectory>Wampler
D
3

I've faced this issue while migrating the Spring Boot project to JDK 17. In the end, the failsafe section of the pom.xml looked like this:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>2.22.2</version>
    <executions>
      <execution>
        <id>integration-test</id>
        <goals>
          <goal>integration-test</goal>
        </goals>
      </execution>
      <execution>
        <id>verify</id>
        <goals>
          <goal>verify</goal>
        </goals>
      </execution>
    </executions>
    <configuration>
      <forkCount>1</forkCount>
      <reuseForks>false</reuseForks>
      <argLine>@{argLine}</argLine>
      <includes>
        <include>**/*IT.java</include>
      </includes>
      <classesDirectory>${project.build.outputDirectory}</classesDirectory>
      <trimStackTrace>false</trimStackTrace>
    </configuration>
    <dependencies>
      <dependency>
        <groupId>org.apache.maven.surefire</groupId>
        <artifactId>surefire-junit47</artifactId>
        <version>2.22.2</version>
      </dependency>
    </dependencies>
  </plugin>
Delaryd answered 15/2, 2023 at 15:48 Comment(2)
Adding classesDirectory solves my problemEmpyema
I was struggling with this problem as well and the classesDirectory option solved. The class loader was struggling to load a class that was in my main package.Clad

© 2022 - 2024 — McMap. All rights reserved.