From c0a91478f127c3860d0f27b4fa2cdfb65ca4ac6b Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 2 Apr 2019 11:38:29 +0100 Subject: [PATCH] Only start management server once main server is initialized Closes gh-15378 --- .../ManagementContextAutoConfiguration.java | 23 +++-------- ...nagementContextAutoConfigurationTests.java | 39 +++++++++---------- 2 files changed, 23 insertions(+), 39 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextAutoConfiguration.java index d657adac71..70c2de2284 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,9 +16,6 @@ package org.springframework.boot.actuate.autoconfigure.web.server; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - import org.springframework.beans.factory.SmartInitializingSingleton; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.boot.actuate.autoconfigure.web.ManagementContextFactory; @@ -29,7 +26,7 @@ import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoCon import org.springframework.boot.context.event.ApplicationFailedEvent; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.web.context.ConfigurableWebServerApplicationContext; -import org.springframework.boot.web.context.WebServerApplicationContext; +import org.springframework.boot.web.context.WebServerInitializedEvent; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; @@ -59,9 +56,6 @@ import org.springframework.util.Assert; ManagementServerProperties.class }) public class ManagementContextAutoConfiguration { - private static final Log logger = LogFactory - .getLog(ManagementContextAutoConfiguration.class); - @Configuration @ConditionalOnManagementPort(ManagementPortType.SAME) static class SameManagementContextConfiguration @@ -122,7 +116,7 @@ public class ManagementContextAutoConfiguration { @Configuration @ConditionalOnManagementPort(ManagementPortType.DIFFERENT) static class DifferentManagementContextConfiguration - implements SmartInitializingSingleton { + implements ApplicationListener { private final ApplicationContext applicationContext; @@ -135,10 +129,8 @@ public class ManagementContextAutoConfiguration { } @Override - public void afterSingletonsInstantiated() { - if (this.applicationContext instanceof WebServerApplicationContext - && ((WebServerApplicationContext) this.applicationContext) - .getWebServer() != null) { + public void onApplicationEvent(WebServerInitializedEvent event) { + if (event.getApplicationContext().equals(this.applicationContext)) { ConfigurableWebServerApplicationContext managementContext = this.managementContextFactory .createManagementContext(this.applicationContext, EnableChildManagementContextConfiguration.class, @@ -150,11 +142,6 @@ public class ManagementContextAutoConfiguration { managementContext); managementContext.refresh(); } - else { - logger.warn("Could not start embedded management container on " - + "different port (management endpoints are still available " - + "through JMX)"); - } } private void setClassLoaderIfPossible(ConfigurableApplicationContext child) { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextAutoConfigurationTests.java index 160b048849..0c83b2f15b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,9 @@ */ package org.springframework.boot.actuate.autoconfigure.web.server; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import org.junit.Rule; import org.junit.Test; @@ -33,28 +36,13 @@ import static org.assertj.core.api.Assertions.assertThat; * Tests for {@link ManagementContextAutoConfiguration}. * * @author Madhura Bhave + * @author Andy Wilkinson */ public class ManagementContextAutoConfigurationTests { - private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of(ManagementContextAutoConfiguration.class, - ServletManagementContextAutoConfiguration.class)); - @Rule public OutputCapture output = new OutputCapture(); - @Test - public void managementServerPortShouldBeIgnoredForNonEmbeddedServer() { - this.contextRunner.withPropertyValues("management.server.port=8081") - .run((context) -> { - assertThat(context.getStartupFailure()).isNull(); - assertThat(this.output.toString()) - .contains("Could not start embedded management container on " - + "different port (management endpoints are still available through JMX)"); - }); - } - @Test public void childManagementContextShouldStartForEmbeddedServer() { WebApplicationContextRunner contextRunner = new WebApplicationContextRunner( @@ -65,10 +53,19 @@ public class ManagementContextAutoConfigurationTests { ServletManagementContextAutoConfiguration.class, WebEndpointAutoConfiguration.class, EndpointAutoConfiguration.class)); - contextRunner.withPropertyValues("management.server.port=8081") - .run((context) -> assertThat(this.output.toString()).doesNotContain( - "Could not start embedded management container on " - + "different port (management endpoints are still available through JMX)")); + contextRunner.withPropertyValues("server.port=0", "management.server.port=0").run( + (context) -> assertThat(tomcatStartedOccurencesIn(this.output.toString())) + .isEqualTo(2)); + + } + + private int tomcatStartedOccurencesIn(String output) { + int matches = 0; + Matcher matcher = Pattern.compile("Tomcat started on port").matcher(output); + while (matcher.find()) { + matches++; + } + return matches; } }