Since Spring boot 3.3.2, system properties and environment variables are not passed to runtime when executing bootTestRun using gradle:

val map = mapOf("abc" to "123")
tasks.named<org.springframework.boot.gradle.tasks.run.BootRun>("bootTestRun") {
    environment(map)
    systemProperties(map)
}

It was working fine in 3.3.1.


3.3.1:

System.getenv("abc"); // output: 123
System.getProperty("abc"); // output: 123

3.3.2:

System.getenv("abc"); // output: null
System.getProperty("abc"); // output: null

Comment From: philwebb

Could you please provide a complete minimal sample (something that we can unzip or git clone, build, and deploy) that reproduces the problem?

Comment From: Eng-Fouad

Could you please provide a complete minimal sample (something that we can unzip or git clone, build, and deploy) that reproduces the problem?

https://github.com/Eng-Fouad/spring-boot-3.3.2-bootTestRun-bug

Comment From: wilkinsona

When the failure occurs, it isn't bootTestRun that's executing, it's processTestAot. When using 3.3.1, processTestAot does very little and doesn't get to the point where the system property or environment is needed. When using 3.3.2, it does get to this point and a failure occurs. We'll need to figure out why processTestAot is behaving differently. In the meantime, the change in behaviour can be worked around with the following additional build configuration:

tasks.named<org.springframework.boot.gradle.tasks.aot.ProcessTestAot>("processTestAot") {
    environment(devSystemProperties)
    systemProperties(devSystemProperties)
}

Comment From: wilkinsona

The change in behavior is due to the fix for #35786.

During AOT processing of tests, TestcontainersLifecycleBeanPostProcessor is called to post-process org.springframework.context.annotation.internalAutowiredAnnotationProcessor. The bean factory's configuration is frozen so it attempts to initialize all container beans. Previously, the use of @RefreshScope on the container bean meant that it wasn't found. With the change made in #35786, the scoped container bean is now found and it's started. Without @RestartScope on the container bean, the problem occurs with 3.3.1.

I think there's a more general problem here and TestcontainersLifecycleBeanPostProcessor shouldn't try to eagerly initialize containers during AOT processing.