question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Document how to configure Maven's Failsafe plugin when not using spring-boot-starter-parent

See original GitHub issue

While migrating an existing application from 2.3.7.RELEASE to 2.4.3 I faced an issue running integration tests complaining with:

java.lang.IllegalStateException: Failed to find merged annotation for @org.springframework.test.context.BootstrapWith(value=org.springframework.boot.test.context.SpringBootTestContextBootstrapper.class)

Find attached a very simple & minimal reproducer case.

Steps

Preparation

spring-reproducer.zip

  • unzip spring-reproducer.zip
  • cd spring-reproducer

OK with 2.3.7.RELEASE

  • mvn clean verify

Failing with 2.4.3

  • mvn -Dspring-boot.version=2.4.3 clean verify

using this version of spring-boot the build fails showing the following details in the failsafe-report

-------------------------------------------------------------------------------
Test set: com.lectra.spring.ApplicationLoaderTestIT
-------------------------------------------------------------------------------
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.136 s <<< FAILURE! - in com.lectra.spring.ApplicationLoaderTestIT
com.lectra.spring.ApplicationLoaderTestIT  Time elapsed: 0.136 s  <<< ERROR!
java.lang.IllegalStateException: Failed to find merged annotation for @org.springframework.test.context.BootstrapWith(value=org.springframework.boot.test.context.SpringBootTestContextBootstrapper.class)

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:10 (7 by maintainers)

github_iconTop GitHub Comments

5reactions
sbrannencommented, Mar 3, 2021

This might be due because of some classloading differences appearing only via failsafe.

It turns out that is indeed the case.

After some debugging and a follow-up brainstorming session with @wilkinsona, we’ve determined that this is effectively a duplicate of https://github.com/spring-projects/spring-boot/issues/6254.

The fact that you resorted to the following should have been an indicator that something was wrong with the classpath.

@SpringBootTest(classes = ErrorReproducerApplication.class)

In a properly structured Spring Boot project, an empty @SpringBootTest declaration should suffice: Spring Boot Test will find your @SpringBootApplication class automatically.

The reason your Maven Failsafe configuration is not working is two-fold.

  1. When using JDK 11, Failsafe is putting the repackaged (by Boot) application JAR on the module-path: <property name="jdk.module.path" value="/path/to/project/target/MyApplication.jar"/>.
  2. When using Failsafe with Spring Boot, Failsafe will by default put the repackaged (by Boot) application JAR on the classpath.

To fix problem # 1, you need to add the following to the <configuration> section of the maven-failsafe-plugin:

<useModulePath>false</useModulePath>

To fix problem # 2, you have some options

  1. https://github.com/spring-projects/spring-boot/issues/6254#issuecomment-229600830
  2. https://github.com/spring-projects/spring-boot/issues/6254#issuecomment-343470070
  3. https://github.com/spring-projects/spring-boot/issues/6254#issuecomment-281404852

I went with option # 3 above and combined that with the first fix, ending up with the following in the <configuration> section of the maven-failsafe-plugin.

<useModulePath>false</useModulePath>
<additionalClasspathElements>
	<additionalClasspathElement>${basedir}/target/classes</additionalClasspathElement>
</additionalClasspathElements>

After that, both test classes pass with the Surefire and Failsafe plugins, respectively.

In light of that, I think this issue should be transferred to Spring Boot to improve the documentation.

p.s. @wilkinsona mentioned that these issues may not have manifested if the project’s POM inherited from the Spring Boot parent POM, but I’ll let him expound on that.

3reactions
wilkinsonacommented, Mar 2, 2021

Thanks, @sbrannen.

spring-boot-starter-parent configures some defaults for Failsafe. Specifically, it configures the <classesDirectory> to be ${project.build.outputDirectory}. I think we should consider documenting this somewhere for the benefit of users whose Maven projects don’t use spring-boot-starter-parent.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Maven Failsafe Plugin – Inclusions and Exclusions of Tests
If the test classes do not follow the default wildcard patterns, then override them by configuring the Failsafe Plugin and specify the tests ......
Read more >
Stop spring boot from executing failsafe plugin - Stack Overflow
When I run mvn integration-test -PmyProfile , maven starts running the default failsafe execution mentioned in the spring dependency first. And ...
Read more >
Spring Boot Maven Plugin Documentation
The Spring Boot Maven Plugin provides Spring Boot support in Apache Maven. It allows you to package executable jar or war archives, ...
Read more >
Spring Boot Starter Parent - Javatpoint
The spring-boot-starter-parent specifies the default configuration for a host of plugins including maven-failsafe-plugin, maven-jar-plugin and ...
Read more >
maven spring-boot-maven-plugin is highlighted in red if ...
But it should work without specifying the version. The version is already set in spring-boot-starter-parent. That is the purpose of this parent!
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found