diff --git a/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/monitoring.adoc b/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/monitoring.adoc index aed5a2acf0e4..8f04b6496d6d 100644 --- a/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/monitoring.adoc +++ b/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/monitoring.adoc @@ -9,8 +9,7 @@ TIP: Actuator is supported natively with Spring MVC, Spring WebFlux, and Jersey. If both Jersey and Spring MVC are available, Spring MVC is used. NOTE: Jackson is a required dependency in order to get the correct JSON responses as documented in the xref:api:rest/actuator/index.adoc[API documentation]. -Jackson 3 should be used for Spring MVC and Spring WebFlux. -Jersey does not yet have a Jackson 3 module, so you will need to use Jackson 2. +Jackson 3 should be used for Spring MVC, Spring WebFlux, and Jersey. diff --git a/integration-test/spring-boot-actuator-integration-tests/build.gradle b/integration-test/spring-boot-actuator-integration-tests/build.gradle index 374e947ed93e..d6ff19e2cacc 100644 --- a/integration-test/spring-boot-actuator-integration-tests/build.gradle +++ b/integration-test/spring-boot-actuator-integration-tests/build.gradle @@ -46,5 +46,4 @@ dependencies { testImplementation("net.minidev:json-smart") testImplementation("org.springframework.security:spring-security-web") testRuntimeOnly("ch.qos.logback:logback-classic") - testRuntimeOnly("com.fasterxml.jackson.datatype:jackson-datatype-jsr310") // Required for Jersey } diff --git a/integration-test/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyWebEndpointIntegrationTests.java b/integration-test/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyWebEndpointIntegrationTests.java index 42e73b807d74..f28ba57af7ea 100644 --- a/integration-test/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyWebEndpointIntegrationTests.java +++ b/integration-test/spring-boot-actuator-integration-tests/src/test/java/org/springframework/boot/actuate/endpoint/web/jersey/JerseyWebEndpointIntegrationTests.java @@ -21,19 +21,19 @@ import java.util.Collection; import java.util.HashSet; -import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.servlet.Filter; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.ws.rs.ext.ContextResolver; -import org.glassfish.jersey.jackson.JacksonFeature; +import org.glassfish.jersey.jackson3.JacksonFeature; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.server.model.Resource; import org.glassfish.jersey.servlet.ServletContainer; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import tools.jackson.databind.json.JsonMapper; import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; import org.springframework.boot.actuate.endpoint.web.EndpointMapping; @@ -121,7 +121,7 @@ ResourceConfig resourceConfig(Environment environment, WebEndpointDiscoverer end new EndpointLinksResolver(endpointDiscoverer.getEndpoints()), StringUtils.hasText(endpointPath)); resourceConfig.registerResources(new HashSet<>(resources)); resourceConfig.register(JacksonFeature.class); - resourceConfig.register(new ObjectMapperContextResolver(new ObjectMapper()), ContextResolver.class); + resourceConfig.register(new JsonMapperContextResolver(new JsonMapper()), ContextResolver.class); return resourceConfig; } @@ -154,17 +154,17 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse } - private static final class ObjectMapperContextResolver implements ContextResolver { + private static final class JsonMapperContextResolver implements ContextResolver { - private final ObjectMapper objectMapper; + private final JsonMapper jsonMapper; - private ObjectMapperContextResolver(ObjectMapper objectMapper) { - this.objectMapper = objectMapper; + private JsonMapperContextResolver(JsonMapper jsonMapper) { + this.jsonMapper = jsonMapper; } @Override - public ObjectMapper getContext(Class type) { - return this.objectMapper; + public JsonMapper getContext(Class type) { + return this.jsonMapper; } } diff --git a/module/spring-boot-jersey/build.gradle b/module/spring-boot-jersey/build.gradle index 8f78e80f98b1..c13a0d6cf171 100644 --- a/module/spring-boot-jersey/build.gradle +++ b/module/spring-boot-jersey/build.gradle @@ -30,16 +30,18 @@ dependencies { api("org.glassfish.jersey.containers:jersey-container-servlet") api("org.glassfish.jersey.core:jersey-server") api("org.glassfish.jersey.ext:jersey-spring6") - api("org.glassfish.jersey.media:jersey-media-json-jackson") + api("org.glassfish.jersey.media:jersey-media-json-jackson3") compileOnly("jakarta.servlet:jakarta.servlet-api") compileOnly("com.google.code.findbugs:jsr305") + compileOnly("org.glassfish.jersey.media:jersey-media-json-jackson") implementation("org.springframework:spring-web") optional(project(":core:spring-boot-autoconfigure")) optional(project(":module:spring-boot-actuator-autoconfigure")) optional(project(":module:spring-boot-health")) + optional(project(":module:spring-boot-jackson")) optional(project(":module:spring-boot-jackson2")) optional(project(":module:spring-boot-micrometer-metrics")) optional(project(":module:spring-boot-micrometer-observation")) @@ -48,7 +50,7 @@ dependencies { testFixturesApi(testFixtures(project(":module:spring-boot-actuator"))) testFixturesImplementation(project(":module:spring-boot-tomcat")) - testFixturesRuntimeOnly(project(":module:spring-boot-jackson2")) + testFixturesRuntimeOnly(project(":module:spring-boot-jackson")) testImplementation(project(":core:spring-boot-test")) testImplementation(project(":module:spring-boot-restclient")) @@ -58,6 +60,8 @@ dependencies { testImplementation("jakarta.servlet:jakarta.servlet-api") testImplementation("org.springframework:spring-webflux") + testCompileOnly("org.glassfish.jersey.media:jersey-media-json-jackson") + testRuntimeOnly("ch.qos.logback:logback-classic") } diff --git a/module/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfiguration.java b/module/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfiguration.java index ad0fb9308fea..3f80bdb25de1 100644 --- a/module/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfiguration.java +++ b/module/spring-boot-jersey/src/main/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfiguration.java @@ -32,6 +32,7 @@ import org.glassfish.jersey.server.spring.SpringComponentProvider; import org.glassfish.jersey.servlet.ServletContainer; import org.glassfish.jersey.servlet.ServletProperties; +import tools.jackson.databind.json.JsonMapper; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Autowired; @@ -66,9 +67,11 @@ * @author Andy Wilkinson * @author Eddú Meléndez * @author Stephane Nicoll + * @author Rene Schakmann * @since 4.0.0 */ -@AutoConfiguration(afterName = { "org.springframework.boot.jackson2.autoconfigure.Jackson2AutoConfiguration" }) +@AutoConfiguration(afterName = { "org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration", + "org.springframework.boot.jackson2.autoconfigure.Jackson2AutoConfiguration" }) @ConditionalOnClass({ SpringComponentProvider.class, ServletRegistration.class }) @ConditionalOnBean(type = "org.glassfish.jersey.server.ResourceConfig") @ConditionalOnWebApplication(type = Type.SERVLET) @@ -175,6 +178,36 @@ public void onStartup(ServletContext servletContext) throws ServletException { } + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass({ org.glassfish.jersey.jackson3.JacksonFeature.class, JsonMapper.class }) + @ConditionalOnSingleCandidate(JsonMapper.class) + static class JacksonResourceConfigCustomizerConfiguration { + + @Bean + ResourceConfigCustomizer jacksonResourceConfigCustomizer(JsonMapper jsonMapper) { + return (ResourceConfig config) -> { + config.register(org.glassfish.jersey.jackson3.JacksonFeature.class); + config.register(new JsonMapperContextResolver(jsonMapper), ContextResolver.class); + }; + } + + private static final class JsonMapperContextResolver implements ContextResolver { + + private final JsonMapper jsonMapper; + + private JsonMapperContextResolver(JsonMapper jsonMapper) { + this.jsonMapper = jsonMapper; + } + + @Override + public JsonMapper getContext(Class type) { + return this.jsonMapper; + } + + } + + } + @Configuration(proxyBeanMethods = false) @ConditionalOnClass(JacksonFeature.class) @ConditionalOnSingleCandidate(com.fasterxml.jackson.databind.ObjectMapper.class) 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 ed288b648a4f..b1fd368119ca 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 @@ -30,6 +30,7 @@ import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.server.model.Resource; import org.jspecify.annotations.Nullable; +import tools.jackson.databind.json.JsonMapper; import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; import org.springframework.boot.actuate.autoconfigure.endpoint.expose.EndpointExposure; @@ -41,6 +42,7 @@ import org.springframework.boot.actuate.endpoint.ExposableEndpoint; import org.springframework.boot.actuate.endpoint.OperationResponseBody; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.actuate.endpoint.jackson.EndpointJsonMapper; import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; import org.springframework.boot.actuate.endpoint.web.EndpointMapping; import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; @@ -71,6 +73,7 @@ * @author Michael Simons * @author Madhura Bhave * @author HaiTao Zhang + * @author Rene Schakmann */ @ManagementContextConfiguration(proxyBeanMethods = false) @ConditionalOnWebApplication(type = Type.SERVLET) @@ -93,6 +96,13 @@ JerseyWebEndpointsResourcesRegistrar jerseyWebEndpointsResourcesRegistrar(Enviro endpointMediaTypes, basePath, shouldRegisterLinks); } + @Bean + @ConditionalOnBean(EndpointJsonMapper.class) + ResourceConfigCustomizer endpointJsonMapperResourceConfigCustomizer(EndpointJsonMapper endpointJsonMapper) { + return (config) -> config.register(new EndpointJsonMapperContextResolver(endpointJsonMapper), + ContextResolver.class); + } + @Bean @ConditionalOnBean(org.springframework.boot.actuate.endpoint.jackson.EndpointJackson2ObjectMapper.class) @SuppressWarnings("removal") @@ -223,6 +233,26 @@ private void register(Collection resources, ResourceConfig config) { } + /** + * {@link ContextResolver} used to obtain the {@link JsonMapper} that should be used + * for {@link OperationResponseBody} instances. + */ + @Priority(Priorities.USER - 100) + private static final class EndpointJsonMapperContextResolver implements ContextResolver { + + private final EndpointJsonMapper mapper; + + private EndpointJsonMapperContextResolver(EndpointJsonMapper mapper) { + this.mapper = mapper; + } + + @Override + public @Nullable JsonMapper getContext(Class type) { + return OperationResponseBody.class.isAssignableFrom(type) ? this.mapper.get() : null; + } + + } + /** * {@link ContextResolver} used to obtain the {@link ObjectMapper} that should be used * for {@link OperationResponseBody} instances. diff --git a/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomObjectMapperProviderTests.java b/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomJsonMapperProviderTests.java similarity index 90% rename from module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomObjectMapperProviderTests.java rename to module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomJsonMapperProviderTests.java index caa2cb0605c0..ea3346dab86b 100644 --- a/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomObjectMapperProviderTests.java +++ b/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationCustomJsonMapperProviderTests.java @@ -32,6 +32,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.http.server.LocalTestWebServer; @@ -47,14 +48,14 @@ import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link JerseyAutoConfiguration} when using custom ObjectMapper. + * Tests for {@link JerseyAutoConfiguration} when using custom JsonMapper. * * @author Eddú Meléndez */ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, - properties = "spring.jackson2.default-property-inclusion=non_null") + properties = "spring.jackson.default-property-inclusion=non_null") @DirtiesContext -class JerseyAutoConfigurationCustomObjectMapperProviderTests { +class JerseyAutoConfigurationCustomJsonMapperProviderTests { @Autowired private ApplicationContext applicationContext; @@ -116,13 +117,11 @@ public void setBody(@Nullable String body) { } - @SuppressWarnings("removal") @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration - @Import({ TomcatServletWebServerAutoConfiguration.class, - org.springframework.boot.jackson2.autoconfigure.Jackson2AutoConfiguration.class, + @Import({ TomcatServletWebServerAutoConfiguration.class, JacksonAutoConfiguration.class, JerseyAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) protected @interface MinimalWebConfiguration { diff --git a/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationJackson2Tests.java b/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationJackson2Tests.java new file mode 100644 index 000000000000..ded949f5bdf4 --- /dev/null +++ b/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationJackson2Tests.java @@ -0,0 +1,108 @@ +/* + * Copyright 2012-present 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.jersey.autoconfigure; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.module.jakarta.xmlbind.JakartaXmlBindAnnotationIntrospector; +import jakarta.ws.rs.ext.ContextResolver; +import org.glassfish.jersey.jackson.JacksonFeature; +import org.glassfish.jersey.server.ResourceConfig; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.testsupport.classpath.ClassPathExclusions; +import org.springframework.boot.testsupport.classpath.ClassPathOverrides; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link JerseyAutoConfiguration} when using Jersey's Jackson 2 support. + * + * @author Andy Wilkinson + * @author Rene Schakmann + */ +@ClassPathExclusions("jersey-media-json-jackson3-*.jar") +@ClassPathOverrides("org.glassfish.jersey.media:jersey-media-json-jackson:4.0.3") +@SuppressWarnings("removal") +class JerseyAutoConfigurationJackson2Tests { + + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(JerseyAutoConfiguration.class, + org.springframework.boot.jackson2.autoconfigure.Jackson2AutoConfiguration.class)) + .withUserConfiguration(ResourceConfigConfiguration.class); + + @Test + void jacksonFeatureAndObjectMapperContextResolverAreRegistered() { + this.contextRunner.run((context) -> { + ResourceConfig config = context.getBean(ResourceConfig.class); + assertThat(config.isRegistered(JacksonFeature.class)).isTrue(); + assertThat(config.getInstances()).anyMatch(ContextResolver.class::isInstance); + }); + } + + @Test + void whenJaxbIsAvailableTheObjectMapperIsCustomizedWithAnAnnotationIntrospector() { + this.contextRunner.run((context) -> { + ObjectMapper objectMapper = context.getBean(ObjectMapper.class); + assertThat(objectMapper.getSerializationConfig() + .getAnnotationIntrospector() + .allIntrospectors() + .stream() + .filter(JakartaXmlBindAnnotationIntrospector.class::isInstance)).hasSize(1); + }); + } + + @Test + void whenJaxbIsNotAvailableTheObjectMapperCustomizationBacksOff() { + this.contextRunner.withClassLoader(new FilteredClassLoader("jakarta.xml.bind.annotation")).run((context) -> { + ObjectMapper objectMapper = context.getBean(ObjectMapper.class); + assertThat(objectMapper.getSerializationConfig() + .getAnnotationIntrospector() + .allIntrospectors() + .stream() + .filter(JakartaXmlBindAnnotationIntrospector.class::isInstance)).isEmpty(); + }); + } + + @Test + void whenJacksonJaxbModuleIsNotAvailableTheObjectMapperCustomizationBacksOff() { + this.contextRunner.withClassLoader(new FilteredClassLoader(JakartaXmlBindAnnotationIntrospector.class)) + .run((context) -> { + ObjectMapper objectMapper = context.getBean(ObjectMapper.class); + assertThat(objectMapper.getSerializationConfig() + .getAnnotationIntrospector() + .allIntrospectors() + .stream() + .filter(JakartaXmlBindAnnotationIntrospector.class::isInstance)).isEmpty(); + }); + } + + @Configuration(proxyBeanMethods = false) + static class ResourceConfigConfiguration { + + @Bean + ResourceConfig resourceConfig() { + return new ResourceConfig(); + } + + } + +} diff --git a/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationObjectMapperProviderTests.java b/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationJsonMapperProviderTests.java similarity index 89% rename from module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationObjectMapperProviderTests.java rename to module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationJsonMapperProviderTests.java index ce145bf2461b..6d02b2a0da38 100644 --- a/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationObjectMapperProviderTests.java +++ b/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationJsonMapperProviderTests.java @@ -33,6 +33,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.http.server.LocalTestWebServer; @@ -48,21 +49,21 @@ import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link JerseyAutoConfiguration} with an ObjectMapper. + * Tests for {@link JerseyAutoConfiguration} with a JsonMapper. * * @author Eddú Meléndez * @author Andy Wilkinson */ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, - properties = "spring.jackson2.default-property-inclusion:non-null") + properties = "spring.jackson.default-property-inclusion:non-null") @DirtiesContext -class JerseyAutoConfigurationObjectMapperProviderTests { +class JerseyAutoConfigurationJsonMapperProviderTests { @Autowired private ApplicationContext applicationContext; @Test - void responseIsSerializedUsingAutoConfiguredObjectMapper() { + void responseIsSerializedUsingAutoConfiguredJsonMapper() { String uri = LocalTestWebServer.obtain(this.applicationContext).uri("/rest/message"); ResponseEntity response = RestClient.create().get().uri(uri).retrieve().toEntity(String.class); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); @@ -130,9 +131,7 @@ public String getFoo() { @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration - @SuppressWarnings("removal") - @Import({ TomcatServletWebServerAutoConfiguration.class, - org.springframework.boot.jackson2.autoconfigure.Jackson2AutoConfiguration.class, + @Import({ TomcatServletWebServerAutoConfiguration.class, JacksonAutoConfiguration.class, JerseyAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) protected @interface MinimalWebConfiguration { diff --git a/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationTests.java b/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationTests.java index 871a55aacd71..d0c14e232ca6 100644 --- a/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationTests.java +++ b/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/JerseyAutoConfigurationTests.java @@ -18,16 +18,16 @@ import java.util.Collections; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.module.jakarta.xmlbind.JakartaXmlBindAnnotationIntrospector; import jakarta.servlet.ServletContext; import jakarta.servlet.ServletException; +import jakarta.ws.rs.ext.ContextResolver; +import org.glassfish.jersey.jackson3.JacksonFeature; import org.glassfish.jersey.server.ResourceConfig; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration.JerseyWebApplicationInitializer; -import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.testsupport.classpath.ClassPathExclusions; import org.springframework.boot.web.servlet.FilterRegistrationBean; @@ -42,6 +42,7 @@ * Tests for {@link JerseyAutoConfiguration}. * * @author Andy Wilkinson + * @author Rene Schakmann */ class JerseyAutoConfigurationTests { @@ -75,53 +76,20 @@ void whenUserDefinesARequestContextFilterRegistrationTheAutoConfiguredRegistrati } @Test - @SuppressWarnings("removal") - void whenJaxbIsAvailableTheObjectMapperIsCustomizedWithAnAnnotationIntrospector() { - this.contextRunner - .withConfiguration(AutoConfigurations - .of(org.springframework.boot.jackson2.autoconfigure.Jackson2AutoConfiguration.class)) - .run((context) -> { - ObjectMapper objectMapper = context.getBean(ObjectMapper.class); - assertThat(objectMapper.getSerializationConfig() - .getAnnotationIntrospector() - .allIntrospectors() - .stream() - .filter(JakartaXmlBindAnnotationIntrospector.class::isInstance)).hasSize(1); - }); - } - - @Test - @SuppressWarnings("removal") - void whenJaxbIsNotAvailableTheObjectMapperCustomizationBacksOff() { - this.contextRunner - .withConfiguration(AutoConfigurations - .of(org.springframework.boot.jackson2.autoconfigure.Jackson2AutoConfiguration.class)) - .withClassLoader(new FilteredClassLoader("jakarta.xml.bind.annotation")) - .run((context) -> { - ObjectMapper objectMapper = context.getBean(ObjectMapper.class); - assertThat(objectMapper.getSerializationConfig() - .getAnnotationIntrospector() - .allIntrospectors() - .stream() - .filter(JakartaXmlBindAnnotationIntrospector.class::isInstance)).isEmpty(); - }); + void jacksonFeatureAndJsonMapperContextResolverAreRegistered() { + this.contextRunner.withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class)).run((context) -> { + ResourceConfig config = context.getBean(ResourceConfig.class); + assertThat(config.isRegistered(JacksonFeature.class)).isTrue(); + assertThat(config.getInstances()).anyMatch(ContextResolver.class::isInstance); + }); } @Test - @SuppressWarnings("removal") - void whenJacksonJaxbModuleIsNotAvailableTheObjectMapperCustomizationBacksOff() { - this.contextRunner - .withConfiguration(AutoConfigurations - .of(org.springframework.boot.jackson2.autoconfigure.Jackson2AutoConfiguration.class)) - .withClassLoader(new FilteredClassLoader(JakartaXmlBindAnnotationIntrospector.class)) - .run((context) -> { - ObjectMapper objectMapper = context.getBean(ObjectMapper.class); - assertThat(objectMapper.getSerializationConfig() - .getAnnotationIntrospector() - .allIntrospectors() - .stream() - .filter(JakartaXmlBindAnnotationIntrospector.class::isInstance)).isEmpty(); - }); + void whenJsonMapperIsNotAvailableJacksonFeatureIsNotRegistered() { + this.contextRunner.run((context) -> { + ResourceConfig config = context.getBean(ResourceConfig.class); + assertThat(config.isRegistered(JacksonFeature.class)).isFalse(); + }); } @Test diff --git a/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/JerseyEndpointAccessIntegrationTests.java b/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/JerseyEndpointAccessIntegrationTests.java index d5553485311f..f94da4013ebd 100644 --- a/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/JerseyEndpointAccessIntegrationTests.java +++ b/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/endpoint/web/JerseyEndpointAccessIntegrationTests.java @@ -31,6 +31,7 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; @@ -53,14 +54,12 @@ */ class JerseyEndpointAccessIntegrationTests { - @SuppressWarnings("removal") private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner( AnnotationConfigServletWebServerApplicationContext::new) - .withConfiguration( - AutoConfigurations.of(org.springframework.boot.jackson2.autoconfigure.Jackson2AutoConfiguration.class, - JerseyAutoConfiguration.class, EndpointAutoConfiguration.class, - TomcatServletWebServerAutoConfiguration.class, WebEndpointAutoConfiguration.class, - ManagementContextAutoConfiguration.class, BeansEndpointAutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class, JerseyAutoConfiguration.class, + EndpointAutoConfiguration.class, TomcatServletWebServerAutoConfiguration.class, + WebEndpointAutoConfiguration.class, ManagementContextAutoConfiguration.class, + BeansEndpointAutoConfiguration.class)) .withUserConfiguration(CustomServletEndpoint.class) .withPropertyValues("server.port:0"); 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 9f89556e6fec..9b51c0f0d24f 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 @@ -16,27 +16,28 @@ package org.springframework.boot.jersey.autoconfigure.actuate.endpoint.web; -import java.io.IOException; import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.jsontype.TypeSerializer; -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 tools.jackson.core.JsonGenerator; +import tools.jackson.databind.SerializationContext; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.jsontype.TypeSerializer; +import tools.jackson.databind.module.SimpleModule; +import tools.jackson.databind.ser.std.StdScalarSerializer; import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; +import org.springframework.boot.actuate.endpoint.jackson.EndpointJsonMapper; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; @@ -85,9 +86,9 @@ void actuatorEndpointsWhenUserProvidedResourceConfigBeanNotAvailable() { } @Test - void endpointObjectMapperCanBeApplied() { + void endpointJsonMapperCanBeApplied() { WebApplicationContextRunner contextRunner = getContextRunner(new Class[] { EndpointsConfiguration.class, - ResourceConfigConfiguration.class, EndpointObjectMapperConfiguration.class }); + ResourceConfigConfiguration.class, EndpointJsonMapperConfiguration.class }); contextRunner.run((context) -> { WebServer webServer = context .getSourceApplicationContext(AnnotationConfigServletWebServerApplicationContext.class) @@ -139,13 +140,11 @@ WebApplicationContextRunner getContextRunner(Class[] userConfigurations, .withPropertyValues("management.endpoints.web.exposure.include:*", "server.port:0"); } - @SuppressWarnings("removal") private Class[] getAutoconfigurations(Class... additional) { - List> autoconfigurations = new ArrayList<>( - Arrays.asList(org.springframework.boot.jackson2.autoconfigure.Jackson2AutoConfiguration.class, - JerseyAutoConfiguration.class, EndpointAutoConfiguration.class, - TomcatServletWebServerAutoConfiguration.class, WebEndpointAutoConfiguration.class, - ManagementContextAutoConfiguration.class, BeansEndpointAutoConfiguration.class)); + List> autoconfigurations = new ArrayList<>(Arrays.asList(JacksonAutoConfiguration.class, + JerseyAutoConfiguration.class, EndpointAutoConfiguration.class, + TomcatServletWebServerAutoConfiguration.class, WebEndpointAutoConfiguration.class, + ManagementContextAutoConfiguration.class, BeansEndpointAutoConfiguration.class)); autoconfigurations.addAll(Arrays.asList(additional)); return autoconfigurations.toArray(new Class[0]); } @@ -187,17 +186,15 @@ ResourceConfig testResourceConfig() { } - @Configuration - @SuppressWarnings({ "deprecation", "removal" }) - static class EndpointObjectMapperConfiguration { + @Configuration(proxyBeanMethods = false) + static class EndpointJsonMapperConfiguration { @Bean - org.springframework.boot.actuate.endpoint.jackson.EndpointJackson2ObjectMapper endpointJackson2ObjectMapper() { + EndpointJsonMapper endpointJsonMapper() { SimpleModule module = new SimpleModule(); module.addSerializer(String.class, new ReverseStringSerializer()); - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.registerModule(module); - return () -> objectMapper; + JsonMapper jsonMapper = JsonMapper.builder().addModule(module).build(); + return () -> jsonMapper; } static class ReverseStringSerializer extends StdScalarSerializer { @@ -207,22 +204,22 @@ static class ReverseStringSerializer extends StdScalarSerializer { } @Override - public boolean isEmpty(SerializerProvider provider, Object value) { + public boolean isEmpty(SerializationContext context, Object value) { return ((String) value).isEmpty(); } @Override - public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException { + public void serialize(Object value, JsonGenerator gen, SerializationContext context) { serialize(value, gen); } @Override - public final void serializeWithType(Object value, JsonGenerator gen, SerializerProvider provider, - TypeSerializer typeSer) throws IOException { + public final void serializeWithType(Object value, JsonGenerator gen, SerializationContext context, + TypeSerializer typeSer) { serialize(value, gen); } - private void serialize(Object value, JsonGenerator gen) throws IOException { + private void serialize(Object value, JsonGenerator gen) { StringBuilder builder = new StringBuilder((String) value); gen.writeString(builder.reverse().toString()); } diff --git a/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyHealthEndpointAdditionalPathIntegrationTests.java b/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyHealthEndpointAdditionalPathIntegrationTests.java index 98fdbeb7f549..cf6156668ff1 100644 --- a/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyHealthEndpointAdditionalPathIntegrationTests.java +++ b/module/spring-boot-jersey/src/test/java/org/springframework/boot/jersey/autoconfigure/actuate/web/JerseyHealthEndpointAdditionalPathIntegrationTests.java @@ -24,6 +24,7 @@ import org.springframework.boot.health.autoconfigure.actuate.endpoint.HealthEndpointAutoConfiguration; import org.springframework.boot.health.autoconfigure.application.DiskSpaceHealthContributorAutoConfiguration; import org.springframework.boot.health.autoconfigure.registry.HealthContributorRegistryAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration; import org.springframework.boot.jersey.autoconfigure.actuate.endpoint.web.HealthEndpointJerseyExtensionAutoConfiguration; import org.springframework.boot.servlet.autoconfigure.actuate.web.ServletManagementContextAutoConfiguration; @@ -43,13 +44,10 @@ class JerseyHealthEndpointAdditionalPathIntegrationTests extends AbstractHealthEndpointAdditionalPathIntegrationTests { - @SuppressWarnings("removal") JerseyHealthEndpointAdditionalPathIntegrationTests() { super(new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new) - .withConfiguration(AutoConfigurations.of( - org.springframework.boot.jackson2.autoconfigure.Jackson2AutoConfiguration.class, - JerseyAutoConfiguration.class, EndpointAutoConfiguration.class, - TomcatServletWebServerAutoConfiguration.class, + .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class, JerseyAutoConfiguration.class, + EndpointAutoConfiguration.class, TomcatServletWebServerAutoConfiguration.class, TomcatServletManagementContextAutoConfiguration.class, WebEndpointAutoConfiguration.class, JerseyAutoConfiguration.class, ManagementContextAutoConfiguration.class, ServletManagementContextAutoConfiguration.class, HealthEndpointAutoConfiguration.class, diff --git a/module/spring-boot-jersey/src/testFixtures/java/org/springframework/boot/jersey/actuate/endpoint/web/test/JerseyEndpointConfiguration.java b/module/spring-boot-jersey/src/testFixtures/java/org/springframework/boot/jersey/actuate/endpoint/web/test/JerseyEndpointConfiguration.java index 7426e9b9eb45..5725622984d1 100644 --- a/module/spring-boot-jersey/src/testFixtures/java/org/springframework/boot/jersey/actuate/endpoint/web/test/JerseyEndpointConfiguration.java +++ b/module/spring-boot-jersey/src/testFixtures/java/org/springframework/boot/jersey/actuate/endpoint/web/test/JerseyEndpointConfiguration.java @@ -29,6 +29,7 @@ import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.boot.jersey.actuate.endpoint.web.JerseyEndpointResourceFactory; import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration; import org.springframework.boot.jersey.autoconfigure.ResourceConfigCustomizer; @@ -43,10 +44,8 @@ * @author Andy Wilkinson * @author Stephane Nicoll */ -@SuppressWarnings("removal") @Configuration(proxyBeanMethods = false) -@ImportAutoConfiguration({ org.springframework.boot.jackson2.autoconfigure.Jackson2AutoConfiguration.class, - JerseyAutoConfiguration.class }) +@ImportAutoConfiguration({ JacksonAutoConfiguration.class, JerseyAutoConfiguration.class }) class JerseyEndpointConfiguration { private final ApplicationContext applicationContext; diff --git a/platform/spring-boot-dependencies/build.gradle b/platform/spring-boot-dependencies/build.gradle index 5da8069319fc..7fafb4317697 100644 --- a/platform/spring-boot-dependencies/build.gradle +++ b/platform/spring-boot-dependencies/build.gradle @@ -1165,7 +1165,7 @@ bom { releaseNotes("https://github.com/redis/jedis/releases/tag/v{version}") } } - library("Jersey", "4.0.2") { + library("Jersey", "4.0.3") { group("org.glassfish.jersey") { bom("jersey-bom") } diff --git a/smoke-test/spring-boot-smoke-test-jersey/src/main/resources/application.properties b/smoke-test/spring-boot-smoke-test-jersey/src/main/resources/application.properties index 0b88415b6aba..1391b10ec6e8 100644 --- a/smoke-test/spring-boot-smoke-test-jersey/src/main/resources/application.properties +++ b/smoke-test/spring-boot-smoke-test-jersey/src/main/resources/application.properties @@ -1,3 +1,2 @@ management.endpoints.web.exposure.include=* management.endpoints.jackson.isolated-json-mapper=true -spring.jackson2.visibility.field=any diff --git a/smoke-test/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/AbstractJerseyApplicationTests.java b/smoke-test/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/AbstractJerseyApplicationTests.java index 4cb5fa7158b5..820b1d914cd8 100644 --- a/smoke-test/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/AbstractJerseyApplicationTests.java +++ b/smoke-test/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/AbstractJerseyApplicationTests.java @@ -61,7 +61,7 @@ void validation() { void actuatorStatus() { ResponseEntity entity = getForEntity("/actuator/health"); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(entity.getBody()).isEqualTo("{\"status\":\"UP\",\"groups\":[\"liveness\",\"readiness\"]}"); + assertThat(entity.getBody()).isEqualTo("{\"groups\":[\"liveness\",\"readiness\"],\"status\":\"UP\"}"); } private ResponseEntity getForEntity(String path) { diff --git a/smoke-test/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedObjectMapperFalseTests.java b/smoke-test/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedJsonMapperFalseTests.java similarity index 74% rename from smoke-test/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedObjectMapperFalseTests.java rename to smoke-test/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedJsonMapperFalseTests.java index d4ec7be37b57..cbc9eec507a4 100644 --- a/smoke-test/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedObjectMapperFalseTests.java +++ b/smoke-test/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedJsonMapperFalseTests.java @@ -16,15 +16,14 @@ package smoketest.jersey; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; +import tools.jackson.databind.json.JsonMapper; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.server.LocalManagementPort; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; -import org.springframework.http.HttpStatusCode; import org.springframework.http.ResponseEntity; import org.springframework.test.context.ContextConfiguration; import org.springframework.web.client.RestClient; @@ -32,14 +31,15 @@ import static org.assertj.core.api.Assertions.assertThat; /** - * Integration test for Jersey actuator when not using an isolated {@link ObjectMapper}. + * Integration test for Jersey actuator when not using an isolated {@link JsonMapper}. * * @author Phillip Webb */ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, - properties = "management.endpoints.jackson2.isolated-object-mapper=false") + properties = { "management.endpoints.jackson.isolated-json-mapper=false", + "spring.jackson.mapper.require-setters-for-getters=true" }) @ContextConfiguration(loader = ApplicationStartupSpringBootContextLoader.class) -class JerseyActuatorIsolatedObjectMapperFalseTests { +class JerseyActuatorIsolatedJsonMapperFalseTests { @LocalServerPort private int port; @@ -48,18 +48,14 @@ class JerseyActuatorIsolatedObjectMapperFalseTests { private int managementPort; @Test - void resourceShouldBeAvailableOnMainPort() { + void bodyIsEmptyDueToMainJsonMapperRequiringSettersForGetters() { ResponseEntity entity = RestClient.create() .get() .uri("http://localhost:" + this.port + "/actuator/startup") .retrieve() - .onStatus(HttpStatusCode::isError, (request, response) -> { - }) .toEntity(String.class); - System.out.println(entity.getBody()); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); - assertThat(entity.getBody()) - .contains("Java 8 date/time type `java.time.Clock$SystemClock` not supported by default"); + assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(entity.getBody()).isEqualTo("{}"); } } diff --git a/smoke-test/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedObjectMapperTrueTests.java b/smoke-test/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedJsonMapperTrueTests.java similarity index 94% rename from smoke-test/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedObjectMapperTrueTests.java rename to smoke-test/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedJsonMapperTrueTests.java index 03397d4dc3e9..58b03475d4b8 100644 --- a/smoke-test/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedObjectMapperTrueTests.java +++ b/smoke-test/spring-boot-smoke-test-jersey/src/test/java/smoketest/jersey/JerseyActuatorIsolatedJsonMapperTrueTests.java @@ -16,8 +16,8 @@ package smoketest.jersey; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; +import tools.jackson.databind.json.JsonMapper; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; @@ -31,14 +31,14 @@ import static org.assertj.core.api.Assertions.assertThat; /** - * Integration test for Jersey actuator when using an isolated {@link ObjectMapper}. + * Integration test for Jersey actuator when using an isolated {@link JsonMapper}. * * @author Phillip Webb */ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = "management.endpoints.jackson.isolated-json-mapper=true") @ContextConfiguration(loader = ApplicationStartupSpringBootContextLoader.class) -class JerseyActuatorIsolatedObjectMapperTrueTests { +class JerseyActuatorIsolatedJsonMapperTrueTests { @LocalServerPort private int port; diff --git a/starter/spring-boot-starter-jersey/build.gradle b/starter/spring-boot-starter-jersey/build.gradle index 6d1ced041da8..4c522b8b8db7 100644 --- a/starter/spring-boot-starter-jersey/build.gradle +++ b/starter/spring-boot-starter-jersey/build.gradle @@ -25,7 +25,7 @@ dependencies { api(project(":starter:spring-boot-starter-tomcat")) api(project(":starter:spring-boot-starter-validation")) - api(project(":module:spring-boot-jackson2")) + api(project(":module:spring-boot-jackson")) api(project(":module:spring-boot-jersey")) api("org.glassfish.jersey.ext:jersey-bean-validation") {