When using the maven-filesafe-plugin the integration-test goal fails during build.

The following error happens under snapshot and 1.4.0.M3 versions. The same configuration is working fine under 1.3.5.RELEASE version.

Failed to execute goal org.apache.maven.plugins:maven-failsafe-plugin:2.19.1:integration-test (default) on project demo: 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
java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy
at sun.reflect.annotation.AnnotationParser.parseClassArray(AnnotationParser.java:724)
at sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:531)
at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:355)
at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:286)
at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120)
at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72)
at java.lang.Class.createAnnotationData(Class.java:3521)
at java.lang.Class.annotationData(Class.java:3510)
at java.lang.Class.getAnnotation(Class.java:3415)
at org.apache.maven.surefire.common.junit4.JUnit4TestChecker.isValidJUnit4Test(JUnit4TestChecker.java:65)
at org.apache.maven.surefire.common.junit4.JUnit4TestChecker.accept(JUnit4TestChecker.java:52)
at org.apache.maven.surefire.util.DefaultScanResult.applyFilter(DefaultScanResult.java:98)
at org.apache.maven.surefire.junit4.JUnit4Provider.scanClassPath(JUnit4Provider.java:311)
at org.apache.maven.surefire.junit4.JUnit4Provider.setTestsToRun(JUnit4Provider.java:191)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:134)
at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:290)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:242)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:121)
-> [Help 1]

Plugins are configured in the following way:

<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <configuration>
                    <includes>
                        <include>**/*IT.java</include>
                    </includes>
                </configuration>
            </plugin>
        </plugins>
</build>

I created a minimal project available here: https://github.com/JIIMI/Spring-Boot-Maven-Failsafe-Plugin-Issue

Comment From: snicoll

@JIIMI thank you so much for the sample, very helpful.

Comment From: snicoll

The same configuration is working fine under 1.3.5.RELEASE version.

That does not make much sense to me. If I paste the code snippet above, it doesn't invoke the failsafe plugin at all (there's no execution). If I put the definition of the failsafe plugin that is provided as of 1.4 in 1.3.5.RELEASE it breaks the same way. What I don't understand is that we've been using the feature quite a lot before adding it to the parent pom

If I remove the classes attributes on the SpringBootTest annotation, the exception goes away.

Maybe related this this SO thread?

Comment From: JIIMI

@snicoll I'm glad it helped. I tried removing the classes attribute before but got the following error:

initializationError(com.example.DemoApplicationIT)  Time elapsed: 0.002 sec  <<< ERROR!
java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test

With the following stack trace:

Running com.example.DemoApplicationIT
10:09:46.586 [main] DEBUG org.springframework.test.context.junit4.SpringJUnit4ClassRunner - SpringJUnit4ClassRunner constructor called with [class com.example.DemoApplicationIT]
10:09:46.597 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating CacheAwareContextLoaderDelegate from class [org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate]
10:09:46.611 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating BootstrapContext using constructor [public org.springframework.test.context.support.DefaultBootstrapContext(java.lang.Class,org.springframework.test.context.CacheAwareContextLoaderDelegate)]
10:09:46.635 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating TestContextBootstrapper for test class [com.example.DemoApplicationIT] from class [org.springframework.boot.test.context.SpringBootTestContextBootstrapper]
10:09:46.652 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Neither @ContextConfiguration nor @ContextHierarchy found for test class [com.example.DemoApplicationIT], using SpringBootContextLoader
10:09:46.659 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [com.example.DemoApplicationIT]: class path resource [com/example/DemoApplicationIT-context.xml] does not exist
10:09:46.659 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [com.example.DemoApplicationIT]: class path resource [com/example/DemoApplicationITContext.groovy] does not exist
10:09:46.660 [main] INFO org.springframework.test.context.support.AbstractContextLoader - Could not detect default resource locations for test class [com.example.DemoApplicationIT]: no resource found for suffixes {-context.xml, Context.groovy}.
10:09:46.662 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils - Could not detect default configuration classes for test class [com.example.DemoApplicationIT]: DemoApplicationIT does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
10:09:46.720 [main] DEBUG org.springframework.test.context.support.ActiveProfilesUtils - Could not find an 'annotation declaring class' for annotation type [org.springframework.test.context.ActiveProfiles] and class [com.example.DemoApplicationIT]
10:09:46.850 [main] DEBUG org.springframework.core.env.StandardEnvironment - Adding [systemProperties] PropertySource with lowest search precedence
10:09:46.850 [main] DEBUG org.springframework.core.env.StandardEnvironment - Adding [systemEnvironment] PropertySource with lowest search precedence
10:09:46.851 [main] DEBUG org.springframework.core.env.StandardEnvironment - Initialized StandardEnvironment with PropertySources [systemProperties,systemEnvironment]
10:09:46.880 [main] DEBUG org.springframework.core.io.support.PathMatchingResourcePatternResolver - Resolved classpath location [com/example/] to resources [URL [file:/D:/user/Documents/NetBeansProjects/!samples/Spring-Boot-Maven-Failsafe-Plugin-Issue/target/test-classes/com/example/]]
10:09:46.881 [main] DEBUG org.springframework.core.io.support.PathMatchingResourcePatternResolver - Looking for matching resources in directory tree [D:\simjir.VCL\Documents\NetBeansProjects\!samples\Spring-Boot-Maven-Failsafe-Plugin-Issue\target\test-classes\com\example]
10:09:46.881 [main] DEBUG org.springframework.core.io.support.PathMatchingResourcePatternResolver - Searching directory [D:\user\Documents\NetBeansProjects\!samples\Spring-Boot-Maven-Failsafe-Plugin-Issue\target\test-classes\com\example] for files matching pattern [D:/user/Documents/NetBeansProjects/!samples/Spring-Boot-Maven-Failsafe-Plugin-Issue/target/test-classes/com/example/*.class]
10:09:46.891 [main] DEBUG org.springframework.core.io.support.PathMatchingResourcePatternResolver - Resolved location pattern [classpath*:com/example/*.class] to resources [file [D:\user\Documents\NetBeansProjects\!samples\Spring-Boot-Maven-Failsafe-Plugin-Issue\target\test-classes\com\example\DemoApplicationIT.class]]
10:09:46.928 [main] DEBUG org.springframework.core.io.support.PathMatchingResourcePatternResolver - Resolved classpath location [com/] to resources [URL [file:/D:/user/Documents/NetBeansProjects/!samples/Spring-Boot-Maven-Failsafe-Plugin-Issue/target/test-classes/com/], URL [jar:file:/C:/Users/user/.m2/repository/com/fasterxml/classmate/1.3.1/classmate-1.3.1.jar!/com/], URL [jar:file:/C:/Users/user/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.7.4/jackson-databind-2.7.4.jar!/com/], URL [jar:file:/C:/Users/user/.m2/repository/com/fasterxml/jackson/core/jackson-annotations/2.7.4/jackson-annotations-2.7.4.jar!/com/], URL [jar:file:/C:/Users/user/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.7.4/jackson-core-2.7.4.jar!/com/], URL [jar:file:/C:/Users/user/.m2/repository/com/jayway/jsonpath/json-path/2.2.0/json-path-2.2.0.jar!/com/]]
10:09:46.929 [main] DEBUG org.springframework.core.io.support.PathMatchingResourcePatternResolver - Looking for matching resources in directory tree [D:\user\Documents\NetBeansProjects\!samples\Spring-Boot-Maven-Failsafe-Plugin-Issue\target\test-classes\com]
10:09:46.929 [main] DEBUG org.springframework.core.io.support.PathMatchingResourcePatternResolver - Searching directory [D:\user\Documents\NetBeansProjects\!samples\Spring-Boot-Maven-Failsafe-Plugin-Issue\target\test-classes\com] for files matching pattern [D:/user/Documents/NetBeansProjects/!samples/Spring-Boot-Maven-Failsafe-Plugin-Issue/target/test-classes/com/*.class]
10:09:46.930 [main] DEBUG org.springframework.core.io.support.PathMatchingResourcePatternResolver - Looking for matching resources in jar file [file:/C:/Users/user/.m2/repository/com/fasterxml/classmate/1.3.1/classmate-1.3.1.jar]
10:09:46.934 [main] DEBUG org.springframework.core.io.support.PathMatchingResourcePatternResolver - Looking for matching resources in jar file [file:/C:/Users/user/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.7.4/jackson-databind-2.7.4.jar]
10:09:46.974 [main] DEBUG org.springframework.core.io.support.PathMatchingResourcePatternResolver - Looking for matching resources in jar file [file:/C:/Users/user/.m2/repository/com/fasterxml/jackson/core/jackson-annotations/2.7.4/jackson-annotations-2.7.4.jar]
10:09:46.975 [main] DEBUG org.springframework.core.io.support.PathMatchingResourcePatternResolver - Looking for matching resources in jar file [file:/C:/Users/user/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.7.4/jackson-core-2.7.4.jar]
10:09:46.976 [main] DEBUG org.springframework.core.io.support.PathMatchingResourcePatternResolver - Looking for matching resources in jar file [file:/C:/Users/user/.m2/repository/com/jayway/jsonpath/json-path/2.2.0/json-path-2.2.0.jar]
10:09:46.978 [main] DEBUG org.springframework.core.io.support.PathMatchingResourcePatternResolver - Resolved location pattern [classpath*:com/*.class] to resources []

Comment From: snicoll

OK that's definitely interesting. It does not find your main spring boot class (which it definitely should).

Comment From: JIIMI

For the:

The same configuration is working fine under 1.3.5.RELEASE version.

You're actually right, the maven-failsafe-plugin isn't invoked. I didn't notice that as I was just looking for the build to succeed since I copied the configuration from our project where it gets invoked and suceeds.

I updated the project with the following configuration:

<plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <configuration>
                    <includes>
                        <include>**/*IT.java</include>
                    </includes>
                </configuration>
                <executions>
                    <execution>
                        <phase>integration-test</phase>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
</plugins>

Now the plugin gets invoked and the integration tests are properly run under version 1.3.5.RELEASE.

Comment From: wilkinsona

This problem is due to a combination of a change in the Failsafe plugin and a change in the layout of a repackaged jar file in Boot 1.4. As of Failsafe 2.19, target/classes is no longer on the classpath and the project's built jar is used instead. In the case of a Boot app, that's the repackaged jar. In 1.4, the application's classes were moved from the root of the jar to the BOOT-INF/classes directory. This prevents them from being loaded by Failsafe.

Comment From: wilkinsona

A workaround is to configure a classifier for the repackaged jar. This allows Failsafe to use the original jar:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <classifier>exec</classifier>
    </configuration>
</plugin>

Comment From: snicoll

Another workaround is to downgrade to the maven-failsafe-plugin to 2.18.1. Funnily enough, I've actually reported the issue to the failsafe tracker but it got rejected.

Comment From: JIIMI

Both indeed works. I guess keeping the 2.19.1 version should be better than using the old version.

@snicoll @wilkinsona Thank you both for your help.

Comment From: snicoll

Unfortunately, the out-of-the-box experience would be very bad with 2.19 so I've reverted to 2.18. I'll follow up on the failsafe issue that I've reopened and once we have a more flexible solution I'll upgrade to 2.19 again.

Thanks for the report!

Comment From: andrashatvani

This should be documented in the release notes.

Comment From: snicoll

@andrashatvani what should be? If you're using the plugin management we provide, everything will work as advertized. So you'll have that issue only if you start overriding things. The release notes is a place to warn users about something we've actually changed. We didn't (the issue was introduced in a 1.4 milestone and fixed in RC).

Comment From: andrashatvani

Sure, but I don't use the plugin management and I bet it's optional for a good reason i.e. we're not the only developers facing this issue. Just put the information in the release notes that one of the two workarounds is necessary if one upgrades to 1.4 and doesn't use the Spring Boot parent.

Comment From: snicoll

You're right, thanks for not letting that go. I've added a section in the release notes.

Comment From: cecchisandrone

Thanks!

Comment From: sepanniemi

Would the fixed failsafe version 2.19.2 work with spring-boot 1.4.x out of the box or is there something else than just dependency update coming to 1.5.x?

Comment From: philwebb

@sepanniemi It should work out the box.

Comment From: deepakab03

I faced the same issue while using spring boot 1.3.3.RELEASE, spring 4.2.5.RELEASE with maven-failsafe-plugin 2.19.1, and this post helped me to find a solution for he same. As a possible fix to this as mentioned above, when I look at upgrading our maven-failsafe-plugin plugin version to 2.19.2 from 2.19.1, I found that 2.19.2 is not available at maven central: http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22maven-failsafe-plugin%22 or at https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-failsafe-plugin Also the documentation page for this plugin states that the latest version is http://maven.apache.org/surefire/maven-failsafe-plugin/index.html is 2.19.1 as of today, so where is this 2.19.2 version published?

Edit: in our case we had some resources in the classes folder that was not added to the jar, but that were used by the tests, to work around it we add the target\classes as an additional classpath element.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <configuration>
        <includes>
            <include>**/*IT.java</include>
        </includes>
            <additionalClasspathElements>
                <additionalClasspathElement>${basedir}/target/classes</additionalClasspathElement>
            </additionalClasspathElements>
            <parallel>none</parallel>
    </configuration>
    <executions>
        <execution>
            <id>integration-test</id>
            <phase>integration-test</phase>
            <goals>
                <goal>integration-test</goal>
                <goal>verify</goal>
            </goals>
        </execution>
    </executions>
</plugin>`

Comment From: wilkinsona

@deepakab03 It hasn't been released yet

Comment From: deepakab03

okay, thanks!

Comment From: mihhail-lapushkin

I am experiencing same issue with 2.20 although in the release notes it mentions that SUREFIRE-1198 is part of 2.20. Should 2.20 work with Spring Boot out of the box? I am using Spring Boot 1.5.X.

Comment From: ideasculptor

Earlier in this thread, someone noted that integration tests aren't invoked at all in a recent spring release, which is why the breakage went undetected. Workarounds for the change in failsafe plugin behaviour were provided, but no one seems to have corrected the spring-boot poms so that integration tests do actually execute if you are using the plugin declaration from the parent hierarchy. When I remove all mention of failsafe and surefire plugins from my pom.xml and then run "mvn verify" it only runs my unit tests. I had to explicitly add the failsafe plugin to get it to actually execute my integration tests, using the latest spring-boot release and parent poms.

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <executions>
      <execution>
        <phase>integration-test</phase>
        <goals>
          <goal>integration-test</goal>
          <goal>verify</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

Comment From: donovanmuller

@mihhail-lapushkin Just switched to 2.20 (using Spring Boot 1.5.3) and same issue. @deepakab03's workaround worked for me...

Comment From: mihhail-lapushkin

Thanks! I am still using 2.18.1 to make it work. My question was more about why 2.20 has not fixed the issue if the unreleased 2.19.2 contained the fix according to some commenters?

Comment From: srgg

Also switched to use 2.20 and Spring Boot 1.5.3 and faced with the same issue... workaround rocks

Comment From: binkley

The exec classifier works for me, but is unfortunate. I also use Boxfuse, which builds a unikernel from the jar, and as the Spring Boot jar has a classifier, Boxfuse picks the wrong jar (the original, un-springified one).

Currently I'm using: - Spring Boot 2.0.0.M1 - Failsafe 2.20 - Boxfuse whatever-is-current (is updates frequently)

Is there a roadmap to get failsafe working out of the box without the exec workaround?

Comment From: binkley

Following a trail of clues, I found an alternative workaround is to restore the behavior in 2.19+ of using target/classes as did 2.18-:

http://maven.apache.org/surefire/maven-failsafe-plugin/integration-test-mojo.html#classesDirectory

So I removed the exec classifier, and added to my failsafe plugin configuration:

<classesDirectory>${project.build.outputDirectory}</classesDirectory>

This allowed both mvn verify and mvn boxfuse:run -Denv=dev to run with the same pom.xml. (FYI, there were other issues, but those relate to boxfuse and Boot 2.x, not to failsafe! -- see boxfuse/boxfuse-issues#174)

Comment From: binkley

I found workaround for using both a renamed spring boot uber jar and boxfuse together.

See https://github.com/boxfuse/boxfuse-issues/issues/174#issuecomment-307159571.

Comment From: hackmann

As an alternative to use target/classes use the original jar before it was repackaged

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <!--
                 Make failsafe and spring-boot repackage play nice together
                -->
                <configuration>
                    <classesDirectory>${project.build.directory}/${artifactId}.jar.original</classesDirectory>
                </configuration>
            </plugin>

This is more in line with failsafe's of testing the packaged jar file instead of the classes

Comment From: mihab

Is there a particular reason why I still need to add this for Spring Boot 2.0 RC1?

exec

ITs fail without it and failsafe plugin.

Comment From: heruan

Same here. Which is nowadays the correct way to make Spring Boot (now 2.0) work with the Failsafe plugin? Any example project?

Comment From: snicoll

This issue is closed and we don't use the tracker for questions: please ask on StackOverflow or join us on Gitter. If you believe you've found an issue with the way the failsafe plugin is configured, please raise a separate issue with a sample that reproduces the problem.

Comment From: wilkinsona

Thanks for try to help people out, @mmuller88, but JUnit 5 is compatible with Maven. The JUnit team maintain a Maven-based sample. Spring Boot also has its own JUnit 5 sample that uses Maven.

Comment From: rdp

See also https://stackoverflow.com/q/42082131/32453 but...this feels unresolved somehow, should a new issue be raised with failsafe perhaps? (FWIW 2.18.1 worked better for me than 2.19.1)

Comment From: naXa777

Take a look at this question https://stackoverflow.com/q/49363222/1429387

Comment From: AndreiOprisan94

I just added the post-integration-test phase

                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${springframework.boot.version}</version>
                <configuration>
                    <mainClass>com.example.MainClass</mainClass>
                    <layout>JAR</layout>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                        <phase>post-integration-test</phase>
                    </execution>
                </executions>

Comment From: sparrowV

adding surefire dependency works for me, dont know exactly why though

<plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>3.0.0-M5</version>
                <dependencies>
                    <dependency>
                        <groupId>org.apache.maven.surefire</groupId>
                        <artifactId>surefire-junit47</artifactId>
                        <version>3.0.0-M5</version>
                    </dependency>
                </dependencies>
            <executions>
                <execution>

                    <goals>
                        <goal>integration-test</goal>
                        <goal>verify</goal>
                    </goals>
                </execution>
            </executions>

            </plugin>

Comment From: lsublimitl

Using Failsafe plugin without parent spring-boot dependency and having a custom directory build path I got this working with the next code:

<build> <directory>docker/app</directory> <plugins> ... <plugin> <artifactId>maven-failsafe-plugin</artifactId> <version>3.0.0-M5</version> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> </execution> </executions> <configuration> <classesDirectory>${project.build.directory}/classes</classesDirectory> </configuration> </plugin> ... </plugins> </build>

Comment From: sudoHackIn

works for me too

Comment From: Marks13

Using Failsafe plugin without parent spring-boot dependency and having a custom directory build path I got this working with the next code:

<build> <directory>docker/app</directory> <plugins> ... <plugin> <artifactId>maven-failsafe-plugin</artifactId> <version>3.0.0-M5</version> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> </execution> </executions> <configuration> <classesDirectory>${project.build.directory}/classes</classesDirectory> </configuration> </plugin> ... </plugins> </build>

As of March 2024 this is still up to date.