From 03b584c26189f7476ec58f061fd7723dae9d9388 Mon Sep 17 00:00:00 2001 From: Kristoffer Larsen Hopland <24739853+khopland@users.noreply.github.com> Date: Sat, 3 Oct 2026 16:24:52 +0200 Subject: [PATCH 1/2] Apply Jersey endpoint Jackson 2 mapper consistently See gh-51937 Signed-off-by: Kristoffer Larsen Hopland <24739853+khopland@users.noreply.github.com> --- ...ndpointManagementContextConfiguration.java | 4 +- .../web/JerseyEndpointIntegrationTests.java | 55 +++++++++++++------ 2 files changed, 39 insertions(+), 20 deletions(-) diff --git a/module/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyWebEndpointManagementContextConfiguration.java b/module/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyWebEndpointManagementContextConfiguration.java index ed288b648a4..624536fb687 100644 --- a/module/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyWebEndpointManagementContextConfiguration.java +++ b/module/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyWebEndpointManagementContextConfiguration.java @@ -56,7 +56,6 @@ import org.springframework.boot.health.actuate.endpoint.HealthEndpoint; import org.springframework.boot.health.actuate.endpoint.HealthEndpointGroups; import org.springframework.boot.jersey.actuate.endpoint.web.JerseyEndpointResourceFactory; import org.springframework.boot.jersey.actuate.endpoint.web.JerseyHealthEndpointAdditionalPathResourceFactory; -import org.springframework.boot.jersey.autoconfigure.ResourceConfigCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; @@ -71,6 +70,7 @@ import org.springframework.util.StringUtils; * @author Michael Simons * @author Madhura Bhave * @author HaiTao Zhang + * @author Kristoffer Larsen Hopland */ @ManagementContextConfiguration(proxyBeanMethods = false) @ConditionalOnWebApplication(type = Type.SERVLET) @@ -96,7 +96,7 @@ class JerseyWebEndpointManagementContextConfiguration { @Bean @ConditionalOnBean(org.springframework.boot.actuate.endpoint.jackson.EndpointJackson2ObjectMapper.class) @SuppressWarnings("removal") - ResourceConfigCustomizer endpointJackson2ObjectMapperResourceConfigCustomizer( + ManagementContextResourceConfigCustomizer endpointJackson2ObjectMapperResourceConfigCustomizer( org.springframework.boot.actuate.endpoint.jackson.EndpointJackson2ObjectMapper endpointJackson2ObjectMapper) { return (config) -> config.register( new EndpointJackson2ObjectMapperContextResolver(endpointJackson2ObjectMapper), ContextResolver.class); diff --git a/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/JerseyEndpointIntegrationTests.java b/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/JerseyEndpointIntegrationTests.java index 9f89556e6fe..21be51be187 100644 --- a/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/JerseyEndpointIntegrationTests.java +++ b/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/JerseyEndpointIntegrationTests.java @@ -31,6 +31,8 @@ import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer; import org.glassfish.jersey.server.ResourceConfig; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; @@ -38,9 +40,12 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAu import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration; +import org.springframework.boot.servlet.autoconfigure.actuate.web.ServletManagementContextAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.tomcat.autoconfigure.actuate.web.server.TomcatServletManagementContextAutoConfiguration; import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.context.ServerPortInfoApplicationContextInitializer; import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -53,6 +58,7 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Andy Wilkinson * @author Madhura Bhave + * @author Kristoffer Larsen Hopland */ class JerseyEndpointIntegrationTests { @@ -84,25 +90,38 @@ class JerseyEndpointIntegrationTests { testJerseyEndpoints(new Class[] { EndpointsConfiguration.class }); } - @Test - void endpointObjectMapperCanBeApplied() { - WebApplicationContextRunner contextRunner = getContextRunner(new Class[] { EndpointsConfiguration.class, - ResourceConfigConfiguration.class, EndpointObjectMapperConfiguration.class }); - contextRunner.run((context) -> { - WebServer webServer = context - .getSourceApplicationContext(AnnotationConfigServletWebServerApplicationContext.class) - .getWebServer(); - assertThat(webServer).isNotNull(); - int port = webServer.getPort(); - WebTestClient client = WebTestClient.bindToServer() - .baseUrl("http://localhost:" + port) - .responseTimeout(Duration.ofMinutes(5)) - .build(); - client.get().uri("/actuator/beans").exchange().expectStatus().isOk().expectBody().consumeWith((result) -> { - String json = new String(result.getResponseBody(), StandardCharsets.UTF_8); - assertThat(json).contains("\"scope\":\"notelgnis\""); + @ParameterizedTest + @ValueSource(booleans = { false, true }) + void endpointObjectMapperCanBeApplied(boolean separateManagementPort) { + getContextRunner( + new Class[] { EndpointsConfiguration.class, ResourceConfigConfiguration.class, + EndpointObjectMapperConfiguration.class }, + TomcatServletManagementContextAutoConfiguration.class, ServletManagementContextAutoConfiguration.class) + .withInitializer(new ServerPortInfoApplicationContextInitializer()) + .withPropertyValues("management.server.port=" + (separateManagementPort ? "0" : "")) + .run((context) -> { + WebServer webServer = context + .getSourceApplicationContext(AnnotationConfigServletWebServerApplicationContext.class) + .getWebServer(); + assertThat(webServer).isNotNull(); + Integer port = separateManagementPort + ? context.getEnvironment().getProperty("local.management.port", Integer.class) + : webServer.getPort(); + assertThat(port).isNotNull(); + WebTestClient.bindToServer() + .baseUrl("http://localhost:" + port) + .build() + .get() + .uri("/actuator/beans") + .exchange() + .expectStatus() + .isOk() + .expectBody() + .consumeWith((result) -> { + String json = new String(result.getResponseBody(), StandardCharsets.UTF_8); + assertThat(json).contains("\"scope\":\"notelgnis\""); + }); }); - }); } protected void testJerseyEndpoints(Class[] userConfigurations) { From 372bd7cb0965b878b8c70df9e6caf4e9e8bdf840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Tue, 6 Oct 2026 10:59:48 +0200 Subject: [PATCH 2/2] Polish "Apply Jersey endpoint Jackson 2 mapper consistently" See gh-51937 --- .../web/JerseyEndpointIntegrationTests.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/JerseyEndpointIntegrationTests.java b/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/JerseyEndpointIntegrationTests.java index 21be51be187..37913840ad6 100644 --- a/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/JerseyEndpointIntegrationTests.java +++ b/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/JerseyEndpointIntegrationTests.java @@ -97,8 +97,7 @@ class JerseyEndpointIntegrationTests { new Class[] { EndpointsConfiguration.class, ResourceConfigConfiguration.class, EndpointObjectMapperConfiguration.class }, TomcatServletManagementContextAutoConfiguration.class, ServletManagementContextAutoConfiguration.class) - .withInitializer(new ServerPortInfoApplicationContextInitializer()) - .withPropertyValues("management.server.port=" + (separateManagementPort ? "0" : "")) + .with((runner) -> setUpManagementPort(runner, separateManagementPort)) .run((context) -> { WebServer webServer = context .getSourceApplicationContext(AnnotationConfigServletWebServerApplicationContext.class) @@ -108,10 +107,11 @@ class JerseyEndpointIntegrationTests { ? context.getEnvironment().getProperty("local.management.port", Integer.class) : webServer.getPort(); assertThat(port).isNotNull(); - WebTestClient.bindToServer() + WebTestClient client = WebTestClient.bindToServer() .baseUrl("http://localhost:" + port) - .build() - .get() + .responseTimeout(Duration.ofMinutes(5)) + .build(); + client.get() .uri("/actuator/beans") .exchange() .expectStatus() @@ -124,6 +124,12 @@ class JerseyEndpointIntegrationTests { }); } + private WebApplicationContextRunner setUpManagementPort(WebApplicationContextRunner runner, + boolean separateManagementPort) { + return (separateManagementPort) ? runner.withInitializer(new ServerPortInfoApplicationContextInitializer()) + .withPropertyValues("management.server.port=0") : runner; + } + protected void testJerseyEndpoints(Class[] userConfigurations) { getContextRunner(userConfigurations).run((context) -> { WebServer webServer = context