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
This commit is contained in:
Dave Syer
2018-03-08 11:55:49 +00:00
parent ce7d9e3092
commit 5802c0e2be
3 changed files with 36 additions and 7 deletions

3
.gitignore vendored
View File

@@ -11,10 +11,11 @@ _site/
.project
.settings
.springBeans
.sts4-cache/
.DS_Store
*.sw*
*.iml
.idea
.factorypath
/spring-cloud-release-tools*.jar
antrun
antrun

View File

@@ -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<Boolean>
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<Boolean>
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) {

View File

@@ -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) {