spring-boot: Maven-failsafe-plugin fails to execute integration tests

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

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 39 (15 by maintainers)

Commits related to this issue

Most upvoted comments

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>

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.

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|ga|1|a%3A"maven-failsafe-plugin" 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>`

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)

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.

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

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

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>

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

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.

This should be documented in the release notes.

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

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>

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>

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.