From 5802c0e2be792738d86509e3d2c93dcd8b997d4d Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 8 Mar 2018 11:55:49 +0000 Subject: [PATCH] Actually close parent context in RestartEndpoint There could be consequences for apps that have more complex context hierarchies, but RestartEndpoint doesn't work well at all for those apps anyway, so we are probably safe to just make changes in the endpoint itself. Fixes gh-333 --- .gitignore | 3 ++- .../context/restart/RestartEndpoint.java | 20 ++++++++++++++++++- .../restart/RestartIntegrationTests.java | 20 ++++++++++++++----- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 86f0d9af..6ee2be21 100644 --- a/.gitignore +++ b/.gitignore @@ -11,10 +11,11 @@ _site/ .project .settings .springBeans +.sts4-cache/ .DS_Store *.sw* *.iml .idea .factorypath /spring-cloud-release-tools*.jar -antrun \ No newline at end of file +antrun diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/restart/RestartEndpoint.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/restart/RestartEndpoint.java index 4454c788..7ac31c36 100644 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/restart/RestartEndpoint.java +++ b/spring-cloud-context/src/main/java/org/springframework/cloud/context/restart/RestartEndpoint.java @@ -16,12 +16,17 @@ package org.springframework.cloud.context.restart; +import java.io.Closeable; +import java.io.IOException; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.boot.SpringApplication; import org.springframework.boot.actuate.endpoint.AbstractEndpoint; import org.springframework.boot.context.event.ApplicationPreparedEvent; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.context.ConfigurableApplicationContext; @@ -155,7 +160,7 @@ public class RestartEndpoint extends AbstractEndpoint this.integrationShutdown.stop(this.timeout); } this.application.setEnvironment(this.context.getEnvironment()); - this.context.close(); + close(); // If running in a webapp then the context classloader is probably going to // die so we need to revert to a safe place before starting again overrideClassLoaderForRestart(); @@ -164,6 +169,19 @@ public class RestartEndpoint extends AbstractEndpoint return this.context; } + private void close() { + ApplicationContext context = this.context; + while (context instanceof Closeable) { + try { + ((Closeable) context).close(); + } + catch (IOException e) { + logger.error("Cannot close context: " + context.getId(), e); + } + context = context.getParent(); + } + } + @ManagedAttribute public boolean isRunning() { if (this.context != null) { diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/restart/RestartIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/restart/RestartIntegrationTests.java index 139d584b..b069c8fe 100644 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/restart/RestartIntegrationTests.java +++ b/spring-cloud-context/src/test/java/org/springframework/cloud/context/restart/RestartIntegrationTests.java @@ -16,16 +16,19 @@ package org.springframework.cloud.context.restart; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.assertNull; - import org.junit.After; import org.junit.Test; + import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.LiveBeansView; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertNull; public class RestartIntegrationTests { @@ -41,7 +44,10 @@ public class RestartIntegrationTests { @Test public void testRestartTwice() throws Exception { - context = SpringApplication.run(TestConfiguration.class, "--endpoints.restart.enabled=true", "--server.port=0"); + context = SpringApplication.run(TestConfiguration.class, + "--endpoints.restart.enabled=true", "--server.port=0", + "--spring.liveBeansView.mbeanDomain=livebeans"); + RestartEndpoint endpoint = context.getBean(RestartEndpoint.class); assertNotNull(context.getParent()); assertNull(context.getParent().getParent()); @@ -59,6 +65,10 @@ public class RestartIntegrationTests { assertNotNull(context.getParent()); assertNull(context.getParent().getParent()); + LiveBeansView beans = new LiveBeansView(); + String json = beans.getSnapshotAsJson(); + assertThat(json).containsOnlyOnce("parent\": \"bootstrap"); + assertThat(json).containsOnlyOnce("parent\": null"); } public static void main(String[] args) {