Skip to content

Failed application contexts are not deregistered from SpringApplicationShutdownHook #29874

@ewirch

Description

@ewirch

Spring Boot: 2.6.3

Assume a mid sized Gradle project having around 4000 classes, and using integration tests (@SpringBootTest).

If there is a bean wiring issue (a bean referenced, but not declared), loading Spring context for integration tests will fail ("No qualifying bean of type ... available"). Gradle will run all tests by default, even if there are test failures. Assuming enough test cases, test execution will fail with an java.lang.OutOfMemoryError: Java heap space. This is really confusing, when looking at build output of a failed CI build (one usually checks the last lines of output).

Why is test execution running out of heap? GC cannot garbage collect failed application context. Path to GC root is:

thread "SpringApplicationShutdownHook" > SpringApplicationShutdownHook class instance > contexts

The context (GenericWebApplicationContext) contains a resourceCaches field, which contains all classes found for Spring context. This is why it needs a mid sized project to trigger the problem after a reasonable amount of tests.

Find a sample project which triggers the behavior attached. The test project fails after 17 tests. Run

./gradlew test

test-project.zip

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions