Skip to content

Commit 764e34b

Browse files
committed
Don’t start child context for actuator endpoints when not embedded
Prior to this commit, EndpointWebMvcAutoConfiguration would start a child context if the management port was different to the server port and the application context was a web application context. This caused two problems: If a user built an executable war and configured the management port so that it was different to the server port, their application would run successfully when launched with java -jar, but it would fail when deployed to Tomcat as an attempt would be made to start embedded Tomcat. Secondly, if a user ran a test annotated with @WebAppConfiguration the main embedded Tomcat instance would not be started, but the child context would trigger the creation of a Tomcat instance listening on the configured management port. This is unexpected as @WebIntegrationTest or @IntegrationTEST and @WebAppConfiguration should be required to have the test trigger full startup of the application and listen on the configured ports. This commit updates EndpointWebMvcAutoConfiguration so that it will only start a child context when the management port is different to the server port and the EmbeddedWebApplicationContext has an embedded servlet container. This resolves the two problems described above as there will be no embedded servlet container when deployed to a standalone container or when a test is run without @IntegrationTEST. Fixes gh-2798
1 parent 0c7708b commit 764e34b

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfiguration.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
import org.springframework.boot.bind.RelaxedPropertyResolver;
6767
import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
6868
import org.springframework.boot.context.embedded.EmbeddedServletContainerException;
69+
import org.springframework.boot.context.embedded.EmbeddedWebApplicationContext;
6970
import org.springframework.boot.context.properties.EnableConfigurationProperties;
7071
import org.springframework.context.ApplicationContext;
7172
import org.springframework.context.ApplicationContextAware;
@@ -148,7 +149,9 @@ public void afterSingletonsInstantiated() {
148149
ManagementServerPort managementPort = ManagementServerPort
149150
.get(this.applicationContext);
150151
if (managementPort == ManagementServerPort.DIFFERENT
151-
&& this.applicationContext instanceof WebApplicationContext) {
152+
&& this.applicationContext instanceof EmbeddedWebApplicationContext
153+
&& ((EmbeddedWebApplicationContext) this.applicationContext)
154+
.getEmbeddedServletContainer() != null) {
152155
createChildManagementContext();
153156
}
154157
if (managementPort == ManagementServerPort.SAME
@@ -375,8 +378,9 @@ private static class OnEnabledEndpointCondition extends SpringBootCondition {
375378
public ConditionOutcome getMatchOutcome(ConditionContext context,
376379
AnnotatedTypeMetadata metadata) {
377380
AnnotationAttributes annotationAttributes = AnnotationAttributes
378-
.fromMap(metadata.getAnnotationAttributes(ConditionalOnEnabledEndpoint.class
379-
.getName()));
381+
.fromMap(metadata
382+
.getAnnotationAttributes(ConditionalOnEnabledEndpoint.class
383+
.getName()));
380384
String endpointName = annotationAttributes.getString("value");
381385
boolean enabledByDefault = annotationAttributes
382386
.getBoolean("enabledByDefault");

spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
import java.net.URI;
2222
import java.nio.charset.Charset;
2323
import java.util.List;
24+
import java.util.Vector;
2425

26+
import javax.servlet.ServletContext;
2527
import javax.servlet.http.HttpServletRequest;
2628
import javax.servlet.http.HttpServletResponse;
2729

@@ -78,6 +80,8 @@
7880
import static org.junit.Assert.assertFalse;
7981
import static org.junit.Assert.assertThat;
8082
import static org.junit.Assert.assertTrue;
83+
import static org.mockito.BDDMockito.given;
84+
import static org.mockito.Mockito.mock;
8185

8286
/**
8387
* Tests for {@link EndpointWebMvcAutoConfiguration}.
@@ -150,6 +154,24 @@ public void onDifferentPort() throws Exception {
150154
assertAllClosed();
151155
}
152156

157+
@Test
158+
public void onDifferentPortInServletContainer() throws Exception {
159+
this.applicationContext.register(RootConfig.class, EndpointConfig.class,
160+
DifferentPortConfig.class, BaseConfiguration.class,
161+
EndpointWebMvcAutoConfiguration.class, ErrorMvcAutoConfiguration.class);
162+
ServletContext servletContext = mock(ServletContext.class);
163+
given(servletContext.getInitParameterNames()).willReturn(
164+
new Vector<String>().elements());
165+
given(servletContext.getAttributeNames()).willReturn(
166+
new Vector<String>().elements());
167+
this.applicationContext.setServletContext(servletContext);
168+
this.applicationContext.refresh();
169+
assertContent("/controller", ports.get().management, null);
170+
assertContent("/endpoint", ports.get().management, null);
171+
this.applicationContext.close();
172+
assertAllClosed();
173+
}
174+
153175
@Test
154176
public void onRandomPort() throws Exception {
155177
this.applicationContext.register(RootConfig.class, EndpointConfig.class,

0 commit comments

Comments
 (0)