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](https://github.com/spring-projects/spring-boot/files/6043007/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)
````


**Comment From: wilkinsona**

Thanks for the sample. This appears to be caused by a regression in Spring Framework. I modified the sample's dependency management so that it uses Spring Framework 5.3.4:

```xml
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-framework-bom</artifactId>
                <version>5.3.4</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>

The failure then occurs with Spring Boot 2.3.x as well as 2.4.x. Interestingly, the failure doesn't occur when running the tests in an IDE so it would also appear to be specific, in some way at least, to using the failsafe plugin.

Comment From: wilkinsona

The exception is thrown from Framework's TestContextAnnotationUtils.AnnotationDescriptor constructor due to the call to AnnotatedElementUtils.findMergedAnnotation(ApplicationLoaderTestIT.class, BootstrapWith.class) returning null. We'll transfer this to the Framework team so that they can take a look.

Comment From: McFoggy

Thank's Andy for the analysis. Indeed I forgot to mention the test was running correctly from an IDE. This might be due because of some classloading differences appearing only via failsafe.

We'll transfer this to the Framework team so that they can take a look.

Perfect.

Comment From: fdimauro

I am seeing the same error, any news on this issue?

Comment From: sbrannen

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.

Comment From: wilkinsona

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.

Comment From: McFoggy

Thanks for the analysis and hints.

Comment From: robert-smith-911

@wilkinsona Something I can take a look at?

Comment From: wilkinsona

Yes please, @robert-smith-911. That'd be great. I think https://docs.spring.io/spring-boot/docs/2.4.2/maven-plugin/reference/htmlsingle/#using-import might be the best place to mention the Failsafe setup, perhaps as a new sub-section.

Comment From: snicoll

Closing in favor of PR #25621