5

Q. How to close the Spring Boot context, created by annotating a test class with @SpringBootTest, before JUnit 5 stops the JVM (which calls the hooks added with addShutdownHook()) ?


Example:
Assuming a bean like this

@Component
public class SomeBean implements DisposableBean {

    public SomeBean() {
        var hook = new Thread(() -> System.out.println("Shutdown Hook called"));
        Runtime.getRuntime().addShutdownHook(hook);
    }

    @Override
    public void destroy() {
        System.out.println("Destroy called");
    }
}

and a simple Junit 5 test like this:

@SpringBootTest
class TestJvmShutdownHookApplicationTests {

    @Test
    void contextLoads() {
    }

}

how do I get the call to destroy() to be performed before the JVM shutdown hook?

2021-02-18 13:54:24.540  INFO 18928 --- [           main] .a.t.TestJvmShutdownHookApplicationTests : Started TestJvmShutdownHookApplicationTests in 2.378 seconds (JVM running for 3.687)
Shutdown Hook called
2021-02-18 13:54:24.863  INFO 18928 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'
Destroy called

Background it.ozimov:embedded-redis adds a JVM shutdown hook and closes the Redis server before the bean redisConnectionFactory (Lettuce) is destroyed.

Andrei Damian-Fekete
  • 1,820
  • 21
  • 27
  • I believe this describes really similar problem: https://stackoverflow.com/questions/48702276/clear-spring-application-context-after-test – Viktar Patotski Feb 18 '21 at 16:02
  • @Viktar Patotski, no, it is not the same and it doesn’t fix my problem. I want to close the context once, after all tests are finished, not after every test or test class. Please reopen. – Andrei Damian-Fekete Feb 19 '21 at 09:36
  • The context is cached, so it will be closed only once. If it closes after each test (or test class) you either have different configs and thus different contexts or are using `@DirtiesContext`. – M. Deinum Feb 23 '21 at 09:08
  • @M.Deinum, in my current situation the context is closed once, but after the JVM executes the shutdown hook (it is closed by Spring's JVM shutdown hook). I want it to be closed once, before the JVM shutdown hooks are executed. – Andrei Damian-Fekete Feb 23 '21 at 12:53
  • There is no guarantee in the shutdown order of the shutdown hooks so there is no foolproof way to do that. I also do'nt see what the issue is, you get an error during shutdown but that can be ignored. – M. Deinum Feb 23 '21 at 13:02
  • @M.Deinum I don't like to ignore errors. On the practical side, the shutdown could also take longer, because the library may try to reconnect to the server a couple of times. – Andrei Damian-Fekete Feb 23 '21 at 15:05

1 Answers1

4

There is currently no built-in support for achieving this.

For further details see the Close all ApplicationContexts in the TestContext framework after all tests have been executed issue in Spring Framework's issue tracker.

Currently, the only way to properly close an ApplicationContext cached by the Spring TestContext Framework is via @DirtiesContext or a custom TestExecutionListener that invokes TestContext#markApplicationContextDirty(...)

Sam Brannen
  • 29,611
  • 5
  • 104
  • 136