Commit 8b9991fc authored by Andy Wilkinson's avatar Andy Wilkinson

Merge branch '2.5.x'

Closes gh-27076
parents 0c01a08b 5a9fa3c8
...@@ -125,6 +125,9 @@ class SpringApplicationShutdownHook implements Runnable { ...@@ -125,6 +125,9 @@ class SpringApplicationShutdownHook implements Runnable {
* @param context the context to clean * @param context the context to clean
*/ */
private void closeAndWait(ConfigurableApplicationContext context) { private void closeAndWait(ConfigurableApplicationContext context) {
if (!context.isActive()) {
return;
}
context.close(); context.close();
try { try {
int waited = 0; int waited = 0;
......
...@@ -26,10 +26,12 @@ import java.util.concurrent.CountDownLatch; ...@@ -26,10 +26,12 @@ import java.util.concurrent.CountDownLatch;
import org.awaitility.Awaitility; import org.awaitility.Awaitility;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
...@@ -91,6 +93,15 @@ class SpringApplicationShutdownHookTests { ...@@ -91,6 +93,15 @@ class SpringApplicationShutdownHookTests {
assertThat(finished).containsExactly(context, handlerAction); assertThat(finished).containsExactly(context, handlerAction);
} }
@Test
void runDueToExitDuringRefreshWhenContextHasBeenClosedDoesNotDeadlock() throws InterruptedException {
GenericApplicationContext context = new GenericApplicationContext();
TestSpringApplicationShutdownHook shutdownHook = new TestSpringApplicationShutdownHook();
shutdownHook.registerApplicationContext(context);
context.registerBean(CloseContextAndExit.class, context, shutdownHook);
context.refresh();
}
@Test @Test
void runWhenContextIsClosedDirectlyRunsHandlerActions() { void runWhenContextIsClosedDirectlyRunsHandlerActions() {
TestSpringApplicationShutdownHook shutdownHook = new TestSpringApplicationShutdownHook(); TestSpringApplicationShutdownHook shutdownHook = new TestSpringApplicationShutdownHook();
...@@ -221,4 +232,28 @@ class SpringApplicationShutdownHookTests { ...@@ -221,4 +232,28 @@ class SpringApplicationShutdownHookTests {
} }
static class CloseContextAndExit implements InitializingBean {
private final ConfigurableApplicationContext context;
private final Runnable shutdownHook;
CloseContextAndExit(ConfigurableApplicationContext context, SpringApplicationShutdownHook shutdownHook) {
this.context = context;
this.shutdownHook = shutdownHook;
}
@Override
public void afterPropertiesSet() throws Exception {
this.context.close();
// Simulate System.exit by running the hook on a separate thread and waiting
// for it to complete
Thread thread = new Thread(this.shutdownHook);
thread.start();
thread.join(15000);
assertThat(thread.isAlive()).isFalse();
}
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment