From 07c9ba0b6a4f5d36772888556e953959e6948949 Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Thu, 18 Jun 2026 15:21:52 +0800 Subject: [PATCH 1/5] Upgrade sdk/spring to Jackson 3 to align with Spring Boot 4 Migrate Jackson 2 (com.fasterxml.jackson.databind/core) to Jackson 3 (tools.jackson) across 10 sdk/spring modules: poms, source, and tests. Jackson 2 annotations are intentionally retained. Cosmos is out of scope. --- eng/versioning/external_dependencies.txt | 3 + sdk/spring/CHANGELOG.md | 74 +++++++++++++++++++ .../pom.xml | 6 +- .../AppConfigurationEndpoint.java | 11 +-- .../AppConfigurationBusRefreshEndpoint.java | 4 +- .../AppConfigurationRefreshEndpoint.java | 4 +- .../AppConfigurationEndpointTest.java | 18 ++--- .../pom.xml | 12 ++- ...rationFeatureManagementPropertySource.java | 4 +- .../implementation/FeatureFlagClient.java | 28 +++---- .../JsonConfigurationParser.java | 23 +++--- ...tionSettingPropertySourceSnapshotTest.java | 5 -- ...nApplicationSettingPropertySourceTest.java | 5 -- .../JsonConfigurationParserTest.java | 4 +- .../config/implementation/TestUtils.java | 12 +-- .../spring-cloud-azure-autoconfigure/pom.xml | 12 +++ .../aad/filter/AadGraphClient.java | 2 +- .../AadClientRegistrationDeserializer.java | 24 +++--- .../jackson/AadClientRegistrationMixin.java | 2 +- ...java => AadOAuth2ClientJacksonModule.java} | 12 +-- .../aad/serde/jackson/JsonNodeUtils.java | 13 ++-- .../aad/serde/jackson/SerializerUtils.java | 36 +++++---- .../aad/serde/jackson/StdConverters.java | 4 +- .../aad/utils/JacksonObjectMapperFactory.java | 2 +- ...reEventHubsMessagingAutoConfiguration.java | 2 +- ...eServiceBusMessagingAutoConfiguration.java | 2 +- ...torageQueueMessagingAutoConfiguration.java | 2 +- .../UserPrincipalMicrosoftGraphTests.java | 7 +- .../aad/security/graph/GraphClientTest.java | 7 +- ...ntHubsMessagingAutoConfigurationTests.java | 15 ++-- ...iceBusMessagingAutoConfigurationTests.java | 15 ++-- ...eQueueMessagingAutoConfigurationTests.java | 15 ++-- .../spring-cloud-azure-docker-compose/pom.xml | 6 +- .../pom.xml | 6 +- .../management/filters/TargetingFilter.java | 6 +- .../management/filters/TimeWindowFilter.java | 19 ++++- .../FeatureManagementProperties.java | 2 +- .../EventHubsBatchMessageConverter.java | 2 +- .../converter/EventHubsMessageConverter.java | 2 +- .../EventHubsBatchMessageConverterTests.java | 16 ++-- .../converter/ServiceBusMessageConverter.java | 2 +- .../StorageQueueMessageConverter.java | 2 +- sdk/spring/spring-messaging-azure/pom.xml | 6 +- .../AbstractJacksonAzureMessageConverter.java | 9 +-- .../converter/ObjectMapperHolder.java | 2 +- 45 files changed, 279 insertions(+), 186 deletions(-) rename sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/serde/jackson/{AadOAuth2ClientJackson2Module.java => AadOAuth2ClientJacksonModule.java} (53%) diff --git a/eng/versioning/external_dependencies.txt b/eng/versioning/external_dependencies.txt index cfc734894b77..d2a2734ef5e9 100644 --- a/eng/versioning/external_dependencies.txt +++ b/eng/versioning/external_dependencies.txt @@ -346,6 +346,7 @@ springboot4_org.springframework.boot:spring-boot-data-redis;4.1.0 springboot4_org.springframework.boot:spring-boot-docker-compose;4.1.0 springboot4_org.springframework.boot:spring-boot-health;4.1.0 springboot4_org.springframework.boot:spring-boot-http-converter;4.1.0 +springboot4_org.springframework.boot:spring-boot-jackson;4.1.0 springboot4_org.springframework.boot:spring-boot-jackson2;4.1.0 springboot4_org.springframework.boot:spring-boot-jdbc;4.1.0 springboot4_org.springframework.boot:spring-boot-jms;4.1.0 @@ -387,6 +388,8 @@ springboot4_org.springframework:spring-web;7.0.8 springboot4_org.springframework:spring-webmvc;7.0.8 springboot4_org.testcontainers:testcontainers-junit-jupiter;2.0.5 springboot4_org.testcontainers:testcontainers-azure;2.0.5 +springboot4_tools.jackson.core:jackson-core;3.1.4 +springboot4_tools.jackson.core:jackson-databind;3.1.4 springboot4_jakarta.annotation:jakarta.annotation-api;3.0.0 springboot4_ch.qos.logback:logback-classic;1.5.34 springboot4_org.awaitility:awaitility;4.3.0 diff --git a/sdk/spring/CHANGELOG.md b/sdk/spring/CHANGELOG.md index 99c776c1184a..bb90663486a1 100644 --- a/sdk/spring/CHANGELOG.md +++ b/sdk/spring/CHANGELOG.md @@ -19,6 +19,80 @@ This section includes changes in `spring-cloud-azure-autoconfigure` module. #### Other Changes +- Upgrade to Jackson 3 to align with Spring Boot 4 ([#49538](https://github.com/Azure/azure-sdk-for-java/issues/49538)). + +### Spring Messaging Azure + +This section includes changes in `spring-messaging-azure` module. + +#### Other Changes + +- Upgrade to Jackson 3 to align with Spring Boot 4 ([#49538](https://github.com/Azure/azure-sdk-for-java/issues/49538)). + +### Spring Messaging Azure Event Hubs + +This section includes changes in `spring-messaging-azure-eventhubs` module. + +#### Other Changes + +- Upgrade to Jackson 3 to align with Spring Boot 4 ([#49538](https://github.com/Azure/azure-sdk-for-java/issues/49538)). + +### Spring Messaging Azure Service Bus + +This section includes changes in `spring-messaging-azure-servicebus` module. + +#### Other Changes + +- Upgrade to Jackson 3 to align with Spring Boot 4 ([#49538](https://github.com/Azure/azure-sdk-for-java/issues/49538)). + +### Spring Messaging Azure Storage Queue + +This section includes changes in `spring-messaging-azure-storage-queue` module. + +#### Other Changes + +- Upgrade to Jackson 3 to align with Spring Boot 4 ([#49538](https://github.com/Azure/azure-sdk-for-java/issues/49538)). + +### Spring Cloud Azure App Configuration Config + +This section includes changes in `spring-cloud-azure-appconfiguration-config` module. + +#### Other Changes + +- Upgrade to Jackson 3 to align with Spring Boot 4 ([#49538](https://github.com/Azure/azure-sdk-for-java/issues/49538)). + +### Spring Cloud Azure App Configuration Config Web + +This section includes changes in `spring-cloud-azure-appconfiguration-config-web` module. + +#### Other Changes + +- Upgrade to Jackson 3 to align with Spring Boot 4 ([#49538](https://github.com/Azure/azure-sdk-for-java/issues/49538)). + +### Spring Cloud Azure Feature Management + +This section includes changes in `spring-cloud-azure-feature-management` module. + +#### Other Changes + +- Upgrade to Jackson 3 to align with Spring Boot 4 ([#49538](https://github.com/Azure/azure-sdk-for-java/issues/49538)). + +### Spring Cloud Azure Actuator Autoconfigure + +This section includes changes in `spring-cloud-azure-actuator-autoconfigure` module. + +#### Other Changes + +- Upgrade to Jackson 3 to align with Spring Boot 4 ([#49538](https://github.com/Azure/azure-sdk-for-java/issues/49538)). + +### Spring Cloud Azure Docker Compose + +This section includes changes in `spring-cloud-azure-docker-compose` module. + +#### Other Changes + +- Upgrade to Jackson 3 to align with Spring Boot 4 ([#49538](https://github.com/Azure/azure-sdk-for-java/issues/49538)). + ## 6.4.0 (2026-06-01) - This release is compatible with Spring Boot 3.5.0-3.5.14. (Note: 3.5.x (x>14) should be supported, but they aren't tested with this release.) - This release is compatible with Spring Cloud 2025.0.0-2025.0.2. (Note: 2025.0.x (x>2) should be supported, but they aren't tested with this release.) diff --git a/sdk/spring/spring-cloud-azure-actuator-autoconfigure/pom.xml b/sdk/spring/spring-cloud-azure-actuator-autoconfigure/pom.xml index cd36ca91f133..6f6252fe9c49 100644 --- a/sdk/spring/spring-cloud-azure-actuator-autoconfigure/pom.xml +++ b/sdk/spring/spring-cloud-azure-actuator-autoconfigure/pom.xml @@ -45,9 +45,9 @@ compile - com.fasterxml.jackson.core + tools.jackson.core jackson-databind - 2.21.4 + 3.1.4 com.azure.spring @@ -198,7 +198,7 @@ - com.fasterxml.jackson.core:jackson-databind:[2.21.4] + tools.jackson.core:jackson-databind:[3.1.4] org.springframework.boot:spring-boot-actuator:[4.1.0] org.springframework.boot:spring-boot-actuator-autoconfigure:[4.1.0] diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config-web/src/main/java/com/azure/spring/cloud/appconfiguration/config/web/implementation/AppConfigurationEndpoint.java b/sdk/spring/spring-cloud-azure-appconfiguration-config-web/src/main/java/com/azure/spring/cloud/appconfiguration/config/web/implementation/AppConfigurationEndpoint.java index bab5c8f2e1d4..b72014f7d8d1 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config-web/src/main/java/com/azure/spring/cloud/appconfiguration/config/web/implementation/AppConfigurationEndpoint.java +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config-web/src/main/java/com/azure/spring/cloud/appconfiguration/config/web/implementation/AppConfigurationEndpoint.java @@ -15,10 +15,11 @@ import com.azure.spring.cloud.appconfiguration.config.implementation.properties.AppConfigurationStoreMonitoring.AccessToken; import com.azure.spring.cloud.appconfiguration.config.implementation.properties.AppConfigurationStoreMonitoring.PushNotification; import com.azure.spring.cloud.appconfiguration.config.implementation.properties.ConfigStore; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.servlet.http.HttpServletRequest; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; /** * Common class for authenticating refresh requests. @@ -37,7 +38,7 @@ public class AppConfigurationEndpoint { private final JsonNode validationResponse; - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = JsonMapper.builder().build(); /** * Base Authentication for refresh endpoints. @@ -63,7 +64,7 @@ public AppConfigurationEndpoint(HttpServletRequest request, List co if (data != null) { JsonNode syncTokenNode = data.findValue(SYNC_TOKEN); if (syncTokenNode != null) { - sToken = syncTokenNode.asText(); + sToken = syncTokenNode.asString(); } } @@ -73,7 +74,7 @@ public AppConfigurationEndpoint(HttpServletRequest request, List co JsonNode requestSubject = requestBody.findValue(CONFIG_STORE_SUBJECT); if (requestSubject != null) { - String subject = requestSubject.asText(); + String subject = requestSubject.asString(); endpoint = URI.create(subject); } else { throw new IllegalArgumentException("Refresh request missing topic field."); diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config-web/src/main/java/com/azure/spring/cloud/appconfiguration/config/web/implementation/pushbusrefresh/AppConfigurationBusRefreshEndpoint.java b/sdk/spring/spring-cloud-azure-appconfiguration-config-web/src/main/java/com/azure/spring/cloud/appconfiguration/config/web/implementation/pushbusrefresh/AppConfigurationBusRefreshEndpoint.java index da435151dd9d..12d52ef67fc0 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config-web/src/main/java/com/azure/spring/cloud/appconfiguration/config/web/implementation/pushbusrefresh/AppConfigurationBusRefreshEndpoint.java +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config-web/src/main/java/com/azure/spring/cloud/appconfiguration/config/web/implementation/pushbusrefresh/AppConfigurationBusRefreshEndpoint.java @@ -22,10 +22,10 @@ import com.azure.spring.cloud.appconfiguration.config.implementation.properties.AppConfigurationProperties; import com.azure.spring.cloud.appconfiguration.config.web.implementation.AppConfigurationEndpoint; -import com.fasterxml.jackson.databind.JsonNode; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import tools.jackson.databind.JsonNode; /** * Endpoint for requesting new configurations to be loaded in all registered instances on the Bus. @@ -82,7 +82,7 @@ public String refresh(HttpServletRequest request, HttpServletResponse response, JsonNode validationResponse = endpoint.getValidationResponse(); if (validationResponse != null) { // Validating Web Hook - return VALIDATION_CODE_FORMAT_START + validationResponse.asText() + "\"}"; + return VALIDATION_CODE_FORMAT_START + validationResponse.asString() + "\"}"; } else { if (!endpoint.authenticate()) { return HttpStatus.UNAUTHORIZED.getReasonPhrase(); diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config-web/src/main/java/com/azure/spring/cloud/appconfiguration/config/web/implementation/pushrefresh/AppConfigurationRefreshEndpoint.java b/sdk/spring/spring-cloud-azure-appconfiguration-config-web/src/main/java/com/azure/spring/cloud/appconfiguration/config/web/implementation/pushrefresh/AppConfigurationRefreshEndpoint.java index 913bbfadd5ab..bc7ce952f549 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config-web/src/main/java/com/azure/spring/cloud/appconfiguration/config/web/implementation/pushrefresh/AppConfigurationRefreshEndpoint.java +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config-web/src/main/java/com/azure/spring/cloud/appconfiguration/config/web/implementation/pushrefresh/AppConfigurationRefreshEndpoint.java @@ -22,10 +22,10 @@ import com.azure.spring.cloud.appconfiguration.config.implementation.properties.AppConfigurationProperties; import com.azure.spring.cloud.appconfiguration.config.web.implementation.AppConfigurationEndpoint; -import com.fasterxml.jackson.databind.JsonNode; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import tools.jackson.databind.JsonNode; /** * Endpoint for requesting new configurations to be loaded. @@ -84,7 +84,7 @@ public String refresh(HttpServletRequest request, HttpServletResponse response, JsonNode validationResponse = endpoint.getValidationResponse(); if (validationResponse != null) { // Validating Web Hook - return String.format("%s%s\"}", VALIDATION_CODE_FORMAT_START, validationResponse.asText()); + return String.format("%s%s\"}", VALIDATION_CODE_FORMAT_START, validationResponse.asString()); } else { if (!endpoint.authenticate()) { return HttpStatus.UNAUTHORIZED.getReasonPhrase(); diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config-web/src/test/java/com/azure/spring/cloud/appconfiguration/config/web/implementation/AppConfigurationEndpointTest.java b/sdk/spring/spring-cloud-azure-appconfiguration-config-web/src/test/java/com/azure/spring/cloud/appconfiguration/config/web/implementation/AppConfigurationEndpointTest.java index aab7e1a959ee..150e9d317248 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config-web/src/test/java/com/azure/spring/cloud/appconfiguration/config/web/implementation/AppConfigurationEndpointTest.java +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config-web/src/test/java/com/azure/spring/cloud/appconfiguration/config/web/implementation/AppConfigurationEndpointTest.java @@ -24,13 +24,11 @@ import org.mockito.MockitoAnnotations; import com.azure.spring.cloud.appconfiguration.config.implementation.properties.ConfigStore; -import com.fasterxml.jackson.core.JsonGenerationException; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.servlet.http.HttpServletRequest; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; public class AppConfigurationEndpointTest { @@ -49,7 +47,7 @@ public class AppConfigurationEndpointTest { private static final String GET_TEST_INVALID = "src/test/resources/webHookInvalid.json"; - private ObjectMapper mapper = new ObjectMapper(); + private ObjectMapper mapper = JsonMapper.builder().build(); @BeforeEach public void setup() throws IOException { @@ -59,7 +57,7 @@ public void setup() throws IOException { } @Test - public void validationParsing() throws JsonGenerationException, JsonMappingException, IOException { + public void validationParsing() throws IOException { String requestBody = mapper.readValue(new File(GET_TEST_VALIDATION), JsonNode.class).toString(); when(lines.collect(Mockito.any())).thenReturn(requestBody); @@ -77,7 +75,7 @@ public void validationParsing() throws JsonGenerationException, JsonMappingExcep } @Test - public void validationInvalidParsing() throws JsonGenerationException, JsonMappingException, IOException { + public void validationInvalidParsing() throws IOException { String requestBody = mapper.readValue(new File(GET_TEST_INVALID), JsonNode.class).toString(); when(lines.collect(Mockito.any())).thenReturn(requestBody); List configStores = new ArrayList(); @@ -88,7 +86,7 @@ public void validationInvalidParsing() throws JsonGenerationException, JsonMappi } @Test - public void authenticate() throws JsonParseException, JsonMappingException, IOException { + public void authenticate() throws IOException { String requestBody = mapper.readValue(new File(GET_TEST_VALIDATION), JsonNode.class).toString(); when(lines.collect(Mockito.any())).thenReturn(requestBody); @@ -158,7 +156,7 @@ public void authenticate() throws JsonParseException, JsonMappingException, IOEx } @Test - public void triggerRefresh() throws JsonParseException, JsonMappingException, IOException { + public void triggerRefresh() throws IOException { String requestBody = mapper.readValue(new File(GET_TEST_VALIDATION), JsonNode.class).toString(); when(lines.collect(Mockito.any())).thenReturn(requestBody); List configStores = new ArrayList(); diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config/pom.xml b/sdk/spring/spring-cloud-azure-appconfiguration-config/pom.xml index 1a37e6ef5511..fabef75255b8 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config/pom.xml +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config/pom.xml @@ -76,6 +76,16 @@ spring-cloud-azure-autoconfigure 7.4.0-beta.1 + + tools.jackson.core + jackson-databind + 3.1.4 + + + com.fasterxml.jackson.core + jackson-annotations + 2.21 + org.springframework.boot @@ -177,7 +187,7 @@ com.fasterxml.jackson.core:jackson-annotations:[2.21] - com.fasterxml.jackson.core:jackson-databind:[2.21.4] + tools.jackson.core:jackson-databind:[3.1.4] org.springframework.boot:spring-boot-actuator:[4.1.0] org.springframework.boot:spring-boot-autoconfigure:[4.1.0] org.springframework.cloud:spring-cloud-context:[5.0.2] diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/AppConfigurationFeatureManagementPropertySource.java b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/AppConfigurationFeatureManagementPropertySource.java index 97efc7c20260..4313b05a141c 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/AppConfigurationFeatureManagementPropertySource.java +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/AppConfigurationFeatureManagementPropertySource.java @@ -6,8 +6,8 @@ import org.springframework.core.env.EnumerablePropertySource; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.json.JsonMapper; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; /** * Azure App Configuration PropertySource unique per Store Label(Profile) combo. diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/FeatureFlagClient.java b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/FeatureFlagClient.java index 0b0c9b440844..16e01de91d7f 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/FeatureFlagClient.java +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/FeatureFlagClient.java @@ -43,11 +43,11 @@ import com.azure.spring.cloud.appconfiguration.config.implementation.feature.entity.FeatureTelemetry; import com.azure.spring.cloud.appconfiguration.config.implementation.feature.entity.Variant; import com.azure.spring.cloud.appconfiguration.config.implementation.http.policy.FeatureFlagTracing; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.MapperFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.json.JsonMapper; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.MapperFeature; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; /** * Loads sets of feature flags, and de-duplicates the results with previously loaded feature flags. Newer Feature Flags @@ -138,7 +138,7 @@ protected static Feature createFeature(FeatureFlagConfigurationSetting item, Str JsonNode node = CASE_INSENSITIVE_MAPPER.readTree(item.getValue()); JsonNode conditions = node.get(CONDITIONS); if (conditions != null && conditions.get(REQUIREMENT_TYPE_SERVICE) != null) { - requirementType = conditions.get(REQUIREMENT_TYPE_SERVICE).asText(); + requirementType = conditions.get(REQUIREMENT_TYPE_SERVICE).asString(); } JsonNode telemetryNode = node.get(TELEMETRY); if (telemetryNode != null && !telemetryNode.isEmpty()) { @@ -179,7 +179,7 @@ protected static Feature createFeature(FeatureFlagConfigurationSetting item, Str originMetadata.put("AllocationId", generateAllocationId(node)); } } - } catch (JsonProcessingException e) { + } catch (JacksonException e) { LOGGER.error("Error parsing feature flag value for key: {}", item.getKey(), e); } return feature; @@ -231,7 +231,7 @@ private void updateTelemetry(FeatureFlagConfigurationSetting featureFlag) { if (variantsNode != null && variantsNode.isArray()) { tracing.updateMaxVariants(variantsNode.size()); } - } catch (JsonProcessingException e) { + } catch (JacksonException e) { LOGGER.warn("Error parsing feature flag telemetry for key: {}", featureFlag.getKey(), e); } } @@ -253,13 +253,13 @@ static String generateAllocationId(JsonNode featureFlagValue) { } // Seed - allocationId.append("seed=").append(allocation.has("seed") ? allocation.get("seed").asText() : ""); + allocationId.append("seed=").append(allocation.has("seed") ? allocation.get("seed").asString() : ""); // DefaultWhenEnabled if (allocation.has("default_when_enabled")) { - allocatedVariants.add(allocation.get("default_when_enabled").asText()); + allocatedVariants.add(allocation.get("default_when_enabled").asString()); } - allocationId.append("\ndefault_when_enabled=").append(allocation.has("default_when_enabled") ? allocation.get("default_when_enabled").asText() : ""); + allocationId.append("\ndefault_when_enabled=").append(allocation.has("default_when_enabled") ? allocation.get("default_when_enabled").asString() : ""); // Percentile allocationId.append("\npercentiles="); @@ -267,7 +267,7 @@ static String generateAllocationId(JsonNode featureFlagValue) { List percentileAllocations = new ArrayList<>(); if (percentile != null && percentile.isArray()) { percentile.forEach(p -> { - if (!Objects.equals(p.get("from").asText(), p.get("to").asText())) { + if (!Objects.equals(p.get("from").asString(), p.get("to").asString())) { percentileAllocations.add(p); } }); @@ -276,13 +276,13 @@ static String generateAllocationId(JsonNode featureFlagValue) { for (JsonNode percentileAllocation : percentileAllocations) { if (percentileAllocation.has("variant")) { - allocatedVariants.add(percentileAllocation.get("variant").asText()); + allocatedVariants.add(percentileAllocation.get("variant").asString()); } } allocationId.append(percentileAllocations.stream() .map(pa -> pa.get("from") + "," - + Base64.getEncoder().encodeToString(pa.get("variant").asText().getBytes(StandardCharsets.UTF_8)) + "," + + Base64.getEncoder().encodeToString(pa.get("variant").asString().getBytes(StandardCharsets.UTF_8)) + "," + pa.get("to")) .collect(Collectors.joining(";"))); diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java index 8ccb807f8188..78aa37383a4a 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java @@ -3,18 +3,17 @@ package com.azure.spring.cloud.appconfiguration.config.implementation; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException; import org.springframework.util.StringUtils; import com.azure.data.appconfiguration.models.ConfigurationSetting; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.json.JsonReadFeature; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.json.JsonMapper; +import tools.jackson.core.JacksonException; +import tools.jackson.core.json.JsonReadFeature; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; public final class JsonConfigurationParser { @@ -55,7 +54,7 @@ static Map parseJsonSetting(ConfigurationSetting setting) try { JsonNode json = MAPPER.readTree(setting.getValue()); parseSetting(setting.getKey(), json, settings); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new InvalidConfigurationPropertyValueException( setting.getKey(), "", @@ -73,15 +72,13 @@ static void parseSetting(String currentKey, JsonNode currentValue, Map fieldNames = currentValue.fieldNames(); - while (fieldNames.hasNext()) { - String fieldName = fieldNames.next(); - String newKey = currentKey + "." + fieldName; - parseSetting(newKey, currentValue.get(fieldName), settings); + for (Map.Entry property : currentValue.properties()) { + String newKey = currentKey + "." + property.getKey(); + parseSetting(newKey, property.getValue(), settings); } break; default: - settings.put(currentKey, currentValue.asText()); + settings.put(currentKey, currentValue.asString()); break; } diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/AppConfigurationApplicationSettingPropertySourceSnapshotTest.java b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/AppConfigurationApplicationSettingPropertySourceSnapshotTest.java index f79e90727f24..85d452ded0ad 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/AppConfigurationApplicationSettingPropertySourceSnapshotTest.java +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/AppConfigurationApplicationSettingPropertySourceSnapshotTest.java @@ -45,8 +45,6 @@ import com.azure.data.appconfiguration.models.FeatureFlagConfigurationSetting; import com.azure.spring.cloud.appconfiguration.config.implementation.http.policy.TracingInfo; import com.azure.spring.cloud.appconfiguration.config.implementation.properties.AppConfigurationProperties; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; public class AppConfigurationApplicationSettingPropertySourceSnapshotTest { @@ -79,8 +77,6 @@ public class AppConfigurationApplicationSettingPropertySourceSnapshotTest { private static final ConfigurationSetting ITEM_NULL = createItem(KEY_FILTER, TEST_KEY_3, TEST_VALUE_3, TEST_LABEL_3, null); - private static final ObjectMapper MAPPER = new ObjectMapper(); - private List testItems = new ArrayList<>(); private AppConfigurationSnapshotPropertySource propertySource; @@ -109,7 +105,6 @@ public static void setup() { @BeforeEach public void init() { session = Mockito.mockitoSession().initMocks(this).strictness(Strictness.STRICT_STUBS).startMocking(); - MAPPER.setPropertyNamingStrategy(PropertyNamingStrategies.KEBAB_CASE); MockitoAnnotations.openMocks(this); diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/AppConfigurationApplicationSettingPropertySourceTest.java b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/AppConfigurationApplicationSettingPropertySourceTest.java index cc1ed8b1620e..972131aa43ee 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/AppConfigurationApplicationSettingPropertySourceTest.java +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/AppConfigurationApplicationSettingPropertySourceTest.java @@ -47,8 +47,6 @@ import com.azure.data.appconfiguration.models.SettingSelector; import com.azure.spring.cloud.appconfiguration.config.implementation.http.policy.TracingInfo; import com.azure.spring.cloud.appconfiguration.config.implementation.properties.AppConfigurationProperties; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; public class AppConfigurationApplicationSettingPropertySourceTest { @@ -78,8 +76,6 @@ public class AppConfigurationApplicationSettingPropertySourceTest { private static final FeatureFlagConfigurationSetting FEATURE_FLAG = createItemFeatureFlag("Beta", "/0"); - private static final ObjectMapper MAPPER = new ObjectMapper(); - private List testItems = new ArrayList<>(); private AppConfigurationApplicationSettingPropertySource propertySource; @@ -106,7 +102,6 @@ public static void setup() { @BeforeEach public void init() { session = Mockito.mockitoSession().initMocks(this).strictness(Strictness.STRICT_STUBS).startMocking(); - MAPPER.setPropertyNamingStrategy(PropertyNamingStrategies.KEBAB_CASE); MockitoAnnotations.openMocks(this); diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParserTest.java b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParserTest.java index 52641e43abc7..480c7519ba6c 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParserTest.java +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParserTest.java @@ -14,8 +14,8 @@ import org.junit.jupiter.api.Test; import com.azure.data.appconfiguration.models.ConfigurationSetting; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; public class JsonConfigurationParserTest { diff --git a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/TestUtils.java b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/TestUtils.java index af7314924a2f..0bf1eef0d351 100644 --- a/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/TestUtils.java +++ b/sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/TestUtils.java @@ -18,10 +18,10 @@ import com.azure.spring.cloud.appconfiguration.config.implementation.properties.AppConfigurationKeyValueSelector; import com.azure.spring.cloud.appconfiguration.config.implementation.properties.AppConfigurationProperties; import com.azure.spring.cloud.appconfiguration.config.implementation.properties.ConfigStore; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.core.JacksonException; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; /** * Utility methods which can be used across different test classes @@ -75,7 +75,7 @@ static FeatureFlagConfigurationSetting createItemFeatureFlag(String prefix, Stri if (clientFiltersNode != null) { for (int i = 0; i < clientFiltersNode.size(); i++) { JsonNode nodeFilter = clientFiltersNode.get(i); - FeatureFlagFilter filter = new FeatureFlagFilter(nodeFilter.get("Name").asText()); + FeatureFlagFilter filter = new FeatureFlagFilter(nodeFilter.get("Name").asString()); JsonNode nodeParams = nodeFilter.get("Parameters"); if (nodeParams != null) { @@ -92,7 +92,7 @@ static FeatureFlagConfigurationSetting createItemFeatureFlag(String prefix, Stri } } } - } catch (JsonProcessingException e) { + } catch (JacksonException e) { LOGGER.log(LogLevel.VERBOSE, () -> "Failed to create FeatureFlagConfigurationSetting.", e); } return item; diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/pom.xml b/sdk/spring/spring-cloud-azure-autoconfigure/pom.xml index d158843e53df..7bff74aa79cb 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/pom.xml +++ b/sdk/spring/spring-cloud-azure-autoconfigure/pom.xml @@ -171,11 +171,21 @@ + + org.springframework.boot + spring-boot-jackson + 4.1.0 + org.springframework.boot spring-boot-jackson2 4.1.0 + + tools.jackson.core + jackson-databind + 3.1.4 + org.springframework.boot:spring-boot-http-converter:[4.1.0] org.springframework.boot:spring-boot-kafka:[4.1.0] + org.springframework.boot:spring-boot-jackson:[4.1.0] org.springframework.boot:spring-boot-jackson2:[4.1.0] org.springframework.boot:spring-boot-jdbc:[4.1.0] org.springframework.boot:spring-boot-jms:[4.1.0] @@ -543,6 +554,7 @@ org.springframework.cloud:spring-cloud-starter-stream-kafka:[5.0.2] org.springframework:spring-context-support:[7.0.8] org.springframework:spring-tx:[7.0.8] + tools.jackson.core:jackson-databind:[3.1.4] diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/filter/AadGraphClient.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/filter/AadGraphClient.java index fe52cb63f35b..4318ee74df2a 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/filter/AadGraphClient.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/filter/AadGraphClient.java @@ -9,7 +9,6 @@ import com.azure.spring.cloud.autoconfigure.implementation.aad.utils.JacksonObjectMapperFactory; import com.azure.spring.cloud.autoconfigure.implementation.aad.configuration.properties.AadAuthenticationProperties; import com.azure.spring.cloud.autoconfigure.implementation.aad.security.properties.AadAuthorizationServerEndpoints; -import com.fasterxml.jackson.databind.ObjectMapper; import com.microsoft.aad.msal4j.ClientCredentialFactory; import com.microsoft.aad.msal4j.ConfidentialClientApplication; import com.microsoft.aad.msal4j.IAuthenticationResult; @@ -28,6 +27,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.web.client.RestOperations; +import tools.jackson.databind.ObjectMapper; import javax.naming.ServiceUnavailableException; import java.io.IOException; diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/serde/jackson/AadClientRegistrationDeserializer.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/serde/jackson/AadClientRegistrationDeserializer.java index fabd56d5b7a8..3dc7c360e20d 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/serde/jackson/AadClientRegistrationDeserializer.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/serde/jackson/AadClientRegistrationDeserializer.java @@ -2,20 +2,17 @@ // Licensed under the MIT License. package com.azure.spring.cloud.autoconfigure.implementation.aad.serde.jackson; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.util.StdConverter; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.core.AuthenticationMethod; import org.springframework.security.oauth2.core.AuthorizationGrantType; import org.springframework.security.oauth2.core.ClientAuthenticationMethod; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.util.StdConverter; -import java.io.IOException; - -class AadClientRegistrationDeserializer extends JsonDeserializer { +class AadClientRegistrationDeserializer extends ValueDeserializer { private static final StdConverter CLIENT_AUTHENTICATION_METHOD_CONVERTER = new StdConverters.ClientAuthenticationMethodConverter(); @@ -27,9 +24,8 @@ class AadClientRegistrationDeserializer extends JsonDeserializer T findValue(JsonNode jsonNode, String fieldName, TypeReference valueTypeReference, - ObjectMapper mapper) { + DeserializationContext context) { if (jsonNode == null) { return null; } JsonNode value = jsonNode.findValue(fieldName); - return (value != null && value.isContainerNode()) ? mapper.convertValue(value, valueTypeReference) : null; + return (value != null && value.isContainer()) + ? context.readTreeAsValue(value, context.getTypeFactory().constructType(valueTypeReference)) : null; } static JsonNode findObjectNode(JsonNode jsonNode, String fieldName) { diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/serde/jackson/SerializerUtils.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/serde/jackson/SerializerUtils.java index 20f17730ac89..f853c8c05b88 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/serde/jackson/SerializerUtils.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/serde/jackson/SerializerUtils.java @@ -2,31 +2,29 @@ // Licensed under the MIT License. package com.azure.spring.cloud.autoconfigure.implementation.aad.serde.jackson; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import org.springframework.security.jackson2.CoreJackson2Module; +import org.springframework.security.jackson.CoreJacksonModule; import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; -import org.springframework.security.oauth2.client.jackson2.OAuth2ClientJackson2Module; +import org.springframework.security.oauth2.client.jackson.OAuth2ClientJacksonModule; +import tools.jackson.core.JacksonException; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.json.JsonMapper; import java.util.Collections; import java.util.Map; -@SuppressWarnings("removal") public final class SerializerUtils { - private static final ObjectMapper OBJECT_MAPPER; + private static final JsonMapper OBJECT_MAPPER; private static final TypeReference> TYPE_REFERENCE = new TypeReference<>() { }; static { - OBJECT_MAPPER = new ObjectMapper(); - OBJECT_MAPPER.registerModule(new OAuth2ClientJackson2Module()); - // Use to handle problem: OAuth2ClientJackson2Module does not support self-defined ClientRegistration type. - // For example: "on_behalf_on" or "azure_delegated". - // TODO(rujche) Delete this after OAuth2ClientJackson2Module support self-defined ClientRegistration type. - OBJECT_MAPPER.registerModule(new AadOAuth2ClientJackson2Module()); - OBJECT_MAPPER.registerModule(new CoreJackson2Module()); - OBJECT_MAPPER.registerModule(new JavaTimeModule()); + OBJECT_MAPPER = JsonMapper.builder() + .addModule(new OAuth2ClientJacksonModule()) + // Use to handle problem: OAuth2ClientJacksonModule does not support self-defined ClientRegistration type. + // For example: "on_behalf_on" or "azure_delegated". + // TODO(rujche) Delete this after OAuth2ClientJacksonModule support self-defined ClientRegistration type. + .addModule(new AadOAuth2ClientJacksonModule()) + .addModule(new CoreJacksonModule()) + .build(); } private SerializerUtils() { @@ -40,8 +38,8 @@ private SerializerUtils() { public static String serializeOAuth2AuthorizedClientMap(Map authorizedClients) { String result; try { - result = OBJECT_MAPPER.writeValueAsString(authorizedClients); - } catch (JsonProcessingException e) { + result = OBJECT_MAPPER.writerFor(TYPE_REFERENCE).writeValueAsString(authorizedClients); + } catch (JacksonException e) { throw new IllegalStateException(e); } return result; @@ -59,7 +57,7 @@ public static Map deserializeOAuth2AuthorizedCli Map authorizedClients; try { authorizedClients = OBJECT_MAPPER.readValue(authorizedClientsString, TYPE_REFERENCE); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new IllegalStateException(e); } return authorizedClients; diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/serde/jackson/StdConverters.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/serde/jackson/StdConverters.java index f5eac1d19ddb..4b0fb5c89127 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/serde/jackson/StdConverters.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/serde/jackson/StdConverters.java @@ -2,11 +2,11 @@ // Licensed under the MIT License. package com.azure.spring.cloud.autoconfigure.implementation.aad.serde.jackson; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.util.StdConverter; import org.springframework.security.oauth2.core.AuthenticationMethod; import org.springframework.security.oauth2.core.AuthorizationGrantType; import org.springframework.security.oauth2.core.ClientAuthenticationMethod; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.util.StdConverter; import static com.azure.spring.cloud.autoconfigure.implementation.aad.security.constants.Constants.ON_BEHALF_OF; diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/utils/JacksonObjectMapperFactory.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/utils/JacksonObjectMapperFactory.java index dc04565bebda..96c58d2f7bf3 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/utils/JacksonObjectMapperFactory.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/utils/JacksonObjectMapperFactory.java @@ -3,7 +3,7 @@ package com.azure.spring.cloud.autoconfigure.implementation.aad.utils; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; /** * factory class of JacksonObjectMapper diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/eventhubs/AzureEventHubsMessagingAutoConfiguration.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/eventhubs/AzureEventHubsMessagingAutoConfiguration.java index abd965fbb8d0..f4a11fde2e6b 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/eventhubs/AzureEventHubsMessagingAutoConfiguration.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/eventhubs/AzureEventHubsMessagingAutoConfiguration.java @@ -23,7 +23,6 @@ import com.azure.spring.messaging.eventhubs.core.properties.ProducerProperties; import com.azure.spring.messaging.eventhubs.implementation.support.converter.EventHubsMessageConverter; import com.azure.spring.messaging.implementation.converter.ObjectMapperHolder; -import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeanUtils; @@ -39,6 +38,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import tools.jackson.databind.ObjectMapper; import static com.azure.spring.cloud.autoconfigure.implementation.context.AzureContextUtils.DEFAULT_TOKEN_CREDENTIAL_BEAN_NAME; import static com.azure.spring.cloud.core.implementation.util.AzurePropertiesUtils.copyAzureCommonProperties; diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusMessagingAutoConfiguration.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusMessagingAutoConfiguration.java index 1a902f6102d1..dff20b6efdb2 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusMessagingAutoConfiguration.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusMessagingAutoConfiguration.java @@ -29,7 +29,6 @@ import com.azure.spring.messaging.servicebus.core.properties.ProcessorProperties; import com.azure.spring.messaging.servicebus.core.properties.ProducerProperties; import com.azure.spring.messaging.servicebus.implementation.support.converter.ServiceBusMessageConverter; -import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeanUtils; @@ -45,6 +44,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import tools.jackson.databind.ObjectMapper; import static com.azure.spring.cloud.autoconfigure.implementation.context.AzureContextUtils.DEFAULT_TOKEN_CREDENTIAL_BEAN_NAME; import static com.azure.spring.cloud.core.implementation.util.AzurePropertiesUtils.copyAzureCommonProperties; diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/storage/queue/AzureStorageQueueMessagingAutoConfiguration.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/storage/queue/AzureStorageQueueMessagingAutoConfiguration.java index fa043796bc00..f629d4c3d601 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/storage/queue/AzureStorageQueueMessagingAutoConfiguration.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/storage/queue/AzureStorageQueueMessagingAutoConfiguration.java @@ -12,7 +12,6 @@ import com.azure.spring.messaging.storage.queue.implementation.factory.DefaultStorageQueueClientFactory; import com.azure.spring.messaging.storage.queue.implementation.support.converter.StorageQueueMessageConverter; import com.azure.storage.queue.models.QueueMessageItem; -import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.BeanUtils; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -22,6 +21,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import tools.jackson.databind.ObjectMapper; import static com.azure.spring.cloud.core.implementation.util.AzurePropertiesUtils.copyAzureCommonProperties; diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/aad/filter/UserPrincipalMicrosoftGraphTests.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/aad/filter/UserPrincipalMicrosoftGraphTests.java index aa31ed3bb442..53a0d3216866 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/aad/filter/UserPrincipalMicrosoftGraphTests.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/aad/filter/UserPrincipalMicrosoftGraphTests.java @@ -7,8 +7,6 @@ import com.azure.core.util.logging.LogLevel; import com.azure.spring.cloud.autoconfigure.implementation.aad.configuration.properties.AadAuthenticationProperties; import com.azure.spring.cloud.autoconfigure.implementation.aad.security.properties.AadAuthorizationServerEndpoints; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; import com.nimbusds.jose.JWSObject; import com.nimbusds.jwt.JWTClaimsSet; import org.junit.jupiter.api.BeforeAll; @@ -22,6 +20,9 @@ import org.springframework.test.web.client.MockRestServiceServer; import org.springframework.util.StringUtils; import org.springframework.web.client.RestTemplate; +import tools.jackson.core.JacksonException; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.ObjectMapper; import java.io.File; import java.io.FileInputStream; @@ -69,7 +70,7 @@ class UserPrincipalMicrosoftGraphTests { new TypeReference>() { }); userGroupsJson = objectMapper.writeValueAsString(json); - } catch (IOException e) { + } catch (JacksonException e) { LOGGER.log(LogLevel.VERBOSE, () -> "Failed to load user groups json.", e); userGroupsJson = null; } diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/aad/security/graph/GraphClientTest.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/aad/security/graph/GraphClientTest.java index c95911f4e558..65ca314eb9d4 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/aad/security/graph/GraphClientTest.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/aad/security/graph/GraphClientTest.java @@ -4,14 +4,13 @@ package com.azure.spring.cloud.autoconfigure.implementation.aad.security.graph; import com.azure.spring.cloud.autoconfigure.implementation.aad.configuration.properties.AadAuthenticationProperties; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.test.web.client.ExpectedCount; import org.springframework.test.web.client.MockRestServiceServer; import org.springframework.web.client.RestTemplate; +import tools.jackson.databind.json.JsonMapper; import java.util.ArrayList; import java.util.Optional; @@ -30,12 +29,12 @@ class GraphClientTest { private static final String FAKE_GRAPH_MEMBERSHIP_URI = "http://localhost:8080/v1.0/me/memberOf"; @Test - void testGetUserMembershipsCorrectly() throws JsonProcessingException { + void testGetUserMembershipsCorrectly() { Memberships memberships = new Memberships(null, new ArrayList<>()); RestTemplate restTemplate = new RestTemplate(); GraphClient graphClient = new GraphClient(new AadAuthenticationProperties(), restTemplate); MockRestServiceServer mockServer = MockRestServiceServer.createServer(restTemplate); - mockServer.expect(ExpectedCount.once(), requestTo(FAKE_GRAPH_MEMBERSHIP_URI)).andRespond(withSuccess(new ObjectMapper().writeValueAsString(memberships), MediaType.APPLICATION_JSON)); + mockServer.expect(ExpectedCount.once(), requestTo(FAKE_GRAPH_MEMBERSHIP_URI)).andRespond(withSuccess(JsonMapper.builder().build().writeValueAsString(memberships), MediaType.APPLICATION_JSON)); Optional userMemberships = graphClient.getUserMemberships(FAKE_ACCESS_TOKEN, FAKE_GRAPH_MEMBERSHIP_URI); diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/eventhubs/AzureEventHubsMessagingAutoConfigurationTests.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/eventhubs/AzureEventHubsMessagingAutoConfigurationTests.java index 6a5520c546d5..97b0baa26516 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/eventhubs/AzureEventHubsMessagingAutoConfigurationTests.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/eventhubs/AzureEventHubsMessagingAutoConfigurationTests.java @@ -15,14 +15,15 @@ import com.azure.spring.messaging.eventhubs.core.EventHubsProducerFactory; import com.azure.spring.messaging.eventhubs.core.EventHubsTemplate; import com.azure.spring.messaging.eventhubs.implementation.support.converter.EventHubsMessageConverter; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.jackson2.autoconfigure.Jackson2AutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; import java.lang.reflect.Field; @@ -92,7 +93,7 @@ void connectionInfoAndCheckpointStoreProvidedShouldConfigure() { void withoutObjectMapperShouldNotConfigure() { this.contextRunner .withClassLoader(new FilteredClassLoader(ObjectMapper.class)) - .withConfiguration(AutoConfigurations.of(Jackson2AutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class)) .withPropertyValues( "spring.cloud.azure.eventhubs.connection-string=" + String.format(CONNECTION_STRING_FORMAT, "test-namespace") ) @@ -106,7 +107,7 @@ void withIsolatedObjectMapper() { this.contextRunner .withPropertyValues("spring.cloud.azure.eventhubs.connection-string=" + String.format(CONNECTION_STRING_FORMAT, "test-namespace")) .withUserConfiguration(AzureEventHubsPropertiesTestConfiguration.class) - .withConfiguration(AutoConfigurations.of(Jackson2AutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class)) .run(context -> { assertThat(context).hasBean("defaultEventHubsMessageConverter"); assertThat(context).hasSingleBean(EventHubsMessageConverter.class); @@ -121,7 +122,7 @@ void withNonIsolatedObjectMapper() { .withPropertyValues("spring.cloud.azure.eventhubs.connection-string=" + String.format(CONNECTION_STRING_FORMAT, "test-namespace"), "spring.cloud.azure.message-converter.isolated-object-mapper=false") .withUserConfiguration(AzureEventHubsPropertiesTestConfiguration.class) - .withConfiguration(AutoConfigurations.of(Jackson2AutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class)) .run(context -> { assertThat(context).hasBean("eventHubsMessageConverter"); assertThat(context).hasSingleBean(EventHubsMessageConverter.class); @@ -136,8 +137,8 @@ void withUserProvidedObjectMapper() { .withPropertyValues("spring.cloud.azure.eventhubs.connection-string=" + String.format(CONNECTION_STRING_FORMAT, "test-namespace"), "spring.cloud.azure.message-converter.isolated-object-mapper=false") .withUserConfiguration(AzureEventHubsPropertiesTestConfiguration.class) - .withBean("userObjectMapper", ObjectMapper.class, () -> new ObjectMapper()) - .withConfiguration(AutoConfigurations.of(Jackson2AutoConfiguration.class)) + .withBean("userObjectMapper", JsonMapper.class, () -> JsonMapper.builder().build()) + .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class)) .run(context -> { assertThat(context).hasBean("userObjectMapper"); assertThat(context).hasSingleBean(ObjectMapper.class); diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusMessagingAutoConfigurationTests.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusMessagingAutoConfigurationTests.java index 66757fb592b4..cdbf11fe47a5 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusMessagingAutoConfigurationTests.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusMessagingAutoConfigurationTests.java @@ -15,14 +15,15 @@ import com.azure.spring.messaging.servicebus.core.ServiceBusProducerFactory; import com.azure.spring.messaging.servicebus.core.ServiceBusTemplate; import com.azure.spring.messaging.servicebus.implementation.support.converter.ServiceBusMessageConverter; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.jackson2.autoconfigure.Jackson2AutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; import java.lang.reflect.Field; @@ -93,7 +94,7 @@ void withoutObjectMapperShouldNotConfigure() { .withPropertyValues( "spring.cloud.azure.servicebus.connection-string=" + String.format(CONNECTION_STRING_FORMAT, "test-namespace") ) - .withConfiguration(AutoConfigurations.of(Jackson2AutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class)) .run(context -> assertThatIllegalStateException()); } @@ -102,7 +103,7 @@ void withoutObjectMapperShouldNotConfigure() { void withIsolatedObjectMapper() { this.contextRunner .withPropertyValues("spring.cloud.azure.servicebus.connection-string=" + String.format(CONNECTION_STRING_FORMAT, "test-namespace")) - .withConfiguration(AutoConfigurations.of(Jackson2AutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class)) .run(context -> { assertThat(context).hasBean("defaultServiceBusMessageConverter"); assertThat(context).hasSingleBean(ServiceBusMessageConverter.class); @@ -116,7 +117,7 @@ void withNonIsolatedObjectMapper() { this.contextRunner .withPropertyValues("spring.cloud.azure.servicebus.connection-string=" + String.format(CONNECTION_STRING_FORMAT, "test-namespace"), "spring.cloud.azure.message-converter.isolated-object-mapper=false") - .withConfiguration(AutoConfigurations.of(Jackson2AutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class)) .run(context -> { assertThat(context).hasBean("serviceBusMessageConverter"); assertThat(context).hasSingleBean(ServiceBusMessageConverter.class); @@ -130,8 +131,8 @@ void withUserProvidedObjectMapper() { this.contextRunner .withPropertyValues("spring.cloud.azure.servicebus.connection-string=" + String.format(CONNECTION_STRING_FORMAT, "test-namespace"), "spring.cloud.azure.message-converter.isolated-object-mapper=false") - .withBean("userObjectMapper", ObjectMapper.class, () -> new ObjectMapper()) - .withConfiguration(AutoConfigurations.of(Jackson2AutoConfiguration.class)) + .withBean("userObjectMapper", JsonMapper.class, () -> JsonMapper.builder().build()) + .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class)) .run(context -> { assertThat(context).hasBean("userObjectMapper"); assertThat(context).hasSingleBean(ObjectMapper.class); diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/storage/AzureStorageQueueMessagingAutoConfigurationTests.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/storage/AzureStorageQueueMessagingAutoConfigurationTests.java index 8e350f23b9d2..44d93208a71a 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/storage/AzureStorageQueueMessagingAutoConfigurationTests.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/storage/AzureStorageQueueMessagingAutoConfigurationTests.java @@ -6,15 +6,16 @@ import com.azure.spring.cloud.autoconfigure.implementation.storage.queue.AzureStorageQueueMessagingAutoConfiguration; import com.azure.spring.cloud.autoconfigure.implementation.storage.queue.properties.AzureStorageQueueProperties; import com.azure.spring.messaging.storage.queue.implementation.support.converter.StorageQueueMessageConverter; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.jackson2.autoconfigure.Jackson2AutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalStateException; @@ -29,7 +30,7 @@ public class AzureStorageQueueMessagingAutoConfigurationTests { void withoutObjectMapperShouldNotConfigure() { this.contextRunner .withClassLoader(new FilteredClassLoader(ObjectMapper.class)) - .withConfiguration(AutoConfigurations.of(Jackson2AutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class)) .withPropertyValues("spring.cloud.azure.storage.queue.enabled=true") .withUserConfiguration(AzureStorageQueuePropertiesTestConfiguration.class) .run(context -> assertThatIllegalStateException()); @@ -40,7 +41,7 @@ void withoutObjectMapperShouldNotConfigure() { void withIsolatedObjectMapper() { this.contextRunner .withPropertyValues("spring.cloud.azure.storage.queue.enabled=true") - .withConfiguration(AutoConfigurations.of(Jackson2AutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class)) .withUserConfiguration(AzureStorageQueuePropertiesTestConfiguration.class) .run(context -> { assertThat(context).hasBean("defaultStorageQueueMessageConverter"); @@ -55,7 +56,7 @@ void withNonIsolatedObjectMapper() { this.contextRunner .withPropertyValues("spring.cloud.azure.storage.queue.enabled=true", "spring.cloud.azure.message-converter.isolated-object-mapper=false") - .withConfiguration(AutoConfigurations.of(Jackson2AutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class)) .withUserConfiguration(AzureStorageQueuePropertiesTestConfiguration.class) .run(context -> { assertThat(context).hasBean("storageQueueMessageConverter"); @@ -70,9 +71,9 @@ void withUserProvidedObjectMapper() { this.contextRunner .withPropertyValues("spring.cloud.azure.storage.queue.enabled=true", "spring.cloud.azure.message-converter.isolated-object-mapper=false") - .withConfiguration(AutoConfigurations.of(Jackson2AutoConfiguration.class)) + .withConfiguration(AutoConfigurations.of(JacksonAutoConfiguration.class)) .withUserConfiguration(AzureStorageQueuePropertiesTestConfiguration.class) - .withBean("userObjectMapper", ObjectMapper.class, () -> new ObjectMapper()) + .withBean("userObjectMapper", JsonMapper.class, () -> JsonMapper.builder().build()) .run(context -> { assertThat(context).hasBean("userObjectMapper"); assertThat(context).hasSingleBean(ObjectMapper.class); diff --git a/sdk/spring/spring-cloud-azure-docker-compose/pom.xml b/sdk/spring/spring-cloud-azure-docker-compose/pom.xml index 690740106067..a3c318a834a0 100644 --- a/sdk/spring/spring-cloud-azure-docker-compose/pom.xml +++ b/sdk/spring/spring-cloud-azure-docker-compose/pom.xml @@ -84,9 +84,9 @@ 4.1.0 - com.fasterxml.jackson.core + tools.jackson.core jackson-databind - 2.21.4 + 3.1.4 + tools.jackson.core:jackson-databind:[3.1.4] org.springframework.boot:spring-boot-docker-compose:[4.1.0] diff --git a/sdk/spring/spring-cloud-azure-feature-management/pom.xml b/sdk/spring/spring-cloud-azure-feature-management/pom.xml index 09d55c963671..67a43c4824be 100644 --- a/sdk/spring/spring-cloud-azure-feature-management/pom.xml +++ b/sdk/spring/spring-cloud-azure-feature-management/pom.xml @@ -54,9 +54,9 @@ 2.21 - com.fasterxml.jackson.core + tools.jackson.core jackson-databind - 2.21.4 + 3.1.4 io.projectreactor.netty @@ -166,7 +166,7 @@ com.fasterxml.jackson.core:jackson-annotations:[2.21] - com.fasterxml.jackson.core:jackson-databind:[2.21.4] + tools.jackson.core:jackson-databind:[3.1.4] io.projectreactor.netty:reactor-netty:[1.3.6] org.springframework.boot:spring-boot-configuration-processor:[4.1.0] org.springframework.boot:spring-boot-starter:[4.1.0] diff --git a/sdk/spring/spring-cloud-azure-feature-management/src/main/java/com/azure/spring/cloud/feature/management/filters/TargetingFilter.java b/sdk/spring/spring-cloud-azure-feature-management/src/main/java/com/azure/spring/cloud/feature/management/filters/TargetingFilter.java index 702e427c0911..07b144b2f580 100644 --- a/sdk/spring/spring-cloud-azure-feature-management/src/main/java/com/azure/spring/cloud/feature/management/filters/TargetingFilter.java +++ b/sdk/spring/spring-cloud-azure-feature-management/src/main/java/com/azure/spring/cloud/feature/management/filters/TargetingFilter.java @@ -22,9 +22,9 @@ import com.azure.spring.cloud.feature.management.targeting.TargetingContextAccessor; import com.azure.spring.cloud.feature.management.targeting.TargetingEvaluationOptions; import com.azure.spring.cloud.feature.management.targeting.TargetingFilterContext; -import com.fasterxml.jackson.databind.MapperFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.json.JsonMapper; +import tools.jackson.databind.MapperFeature; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; /** * `Microsoft.TargetingFilter` enables evaluating a user/group/overall rollout of a feature. diff --git a/sdk/spring/spring-cloud-azure-feature-management/src/main/java/com/azure/spring/cloud/feature/management/filters/TimeWindowFilter.java b/sdk/spring/spring-cloud-azure-feature-management/src/main/java/com/azure/spring/cloud/feature/management/filters/TimeWindowFilter.java index a25274677a09..f81f9cc6e4bb 100644 --- a/sdk/spring/spring-cloud-azure-feature-management/src/main/java/com/azure/spring/cloud/feature/management/filters/TimeWindowFilter.java +++ b/sdk/spring/spring-cloud-azure-feature-management/src/main/java/com/azure/spring/cloud/feature/management/filters/TimeWindowFilter.java @@ -17,9 +17,10 @@ import com.azure.spring.cloud.feature.management.implementation.timewindow.recurrence.RecurrenceConstants; import com.azure.spring.cloud.feature.management.implementation.timewindow.recurrence.RecurrenceEvaluator; import com.azure.spring.cloud.feature.management.models.FeatureFilterEvaluationContext; -import com.fasterxml.jackson.databind.MapperFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.json.JsonMapper; +import tools.jackson.databind.DatabindException; +import tools.jackson.databind.MapperFeature; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; /** * A feature filter that can be used at activate a feature based on a time window. @@ -55,7 +56,17 @@ public boolean evaluate(FeatureFilterEvaluationContext context) { } } - final TimeWindowFilterSettings settings = OBJECT_MAPPER.convertValue(context.getParameters(), TimeWindowFilterSettings.class); + final TimeWindowFilterSettings settings; + try { + settings = OBJECT_MAPPER.convertValue(context.getParameters(), TimeWindowFilterSettings.class); + } catch (final DatabindException e) { + // Jackson 3 wraps exceptions thrown by setters (such as IllegalArgumentException raised during + // recurrence validation) in DatabindException. Preserve the original IllegalArgumentException contract. + if (e.getCause() instanceof IllegalArgumentException) { + throw (IllegalArgumentException) e.getCause(); + } + throw new IllegalArgumentException(e.getMessage(), e); + } final ZonedDateTime now = ZonedDateTime.now(); if (settings.getStart() == null && settings.getEnd() == null) { diff --git a/sdk/spring/spring-cloud-azure-feature-management/src/main/java/com/azure/spring/cloud/feature/management/implementation/FeatureManagementProperties.java b/sdk/spring/spring-cloud-azure-feature-management/src/main/java/com/azure/spring/cloud/feature/management/implementation/FeatureManagementProperties.java index d0101afdfdb8..b278a367a86f 100644 --- a/sdk/spring/spring-cloud-azure-feature-management/src/main/java/com/azure/spring/cloud/feature/management/implementation/FeatureManagementProperties.java +++ b/sdk/spring/spring-cloud-azure-feature-management/src/main/java/com/azure/spring/cloud/feature/management/implementation/FeatureManagementProperties.java @@ -9,7 +9,7 @@ import com.azure.spring.cloud.feature.management.models.FeatureDefinition; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; /** * Configuration Properties for Feature Management. Processes the configurations to be usable by Feature Management. diff --git a/sdk/spring/spring-messaging-azure-eventhubs/src/main/java/com/azure/spring/messaging/eventhubs/implementation/support/converter/EventHubsBatchMessageConverter.java b/sdk/spring/spring-messaging-azure-eventhubs/src/main/java/com/azure/spring/messaging/eventhubs/implementation/support/converter/EventHubsBatchMessageConverter.java index 85995f224925..6638c5a5066e 100644 --- a/sdk/spring/spring-messaging-azure-eventhubs/src/main/java/com/azure/spring/messaging/eventhubs/implementation/support/converter/EventHubsBatchMessageConverter.java +++ b/sdk/spring/spring-messaging-azure-eventhubs/src/main/java/com/azure/spring/messaging/eventhubs/implementation/support/converter/EventHubsBatchMessageConverter.java @@ -7,11 +7,11 @@ import com.azure.spring.messaging.AzureHeaders; import com.azure.spring.messaging.implementation.converter.AbstractJacksonAzureMessageConverter; import com.azure.spring.messaging.eventhubs.support.EventHubsHeaders; -import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.messaging.Message; import org.springframework.messaging.MessageHeaders; import org.springframework.messaging.support.MessageBuilder; import org.springframework.util.Assert; +import tools.jackson.databind.ObjectMapper; import java.nio.charset.StandardCharsets; import java.util.ArrayList; diff --git a/sdk/spring/spring-messaging-azure-eventhubs/src/main/java/com/azure/spring/messaging/eventhubs/implementation/support/converter/EventHubsMessageConverter.java b/sdk/spring/spring-messaging-azure-eventhubs/src/main/java/com/azure/spring/messaging/eventhubs/implementation/support/converter/EventHubsMessageConverter.java index 07a55eaf6729..dc737b01db7b 100644 --- a/sdk/spring/spring-messaging-azure-eventhubs/src/main/java/com/azure/spring/messaging/eventhubs/implementation/support/converter/EventHubsMessageConverter.java +++ b/sdk/spring/spring-messaging-azure-eventhubs/src/main/java/com/azure/spring/messaging/eventhubs/implementation/support/converter/EventHubsMessageConverter.java @@ -7,11 +7,11 @@ import com.azure.spring.messaging.AzureHeaders; import com.azure.spring.messaging.implementation.converter.AbstractJacksonAzureMessageConverter; import com.azure.spring.messaging.eventhubs.support.EventHubsHeaders; -import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.messaging.Message; import org.springframework.messaging.MessageHeaders; +import tools.jackson.databind.ObjectMapper; import java.nio.charset.StandardCharsets; import java.util.Arrays; diff --git a/sdk/spring/spring-messaging-azure-eventhubs/src/test/java/com/azure/spring/messaging/eventhubs/implementation/support/converter/EventHubsBatchMessageConverterTests.java b/sdk/spring/spring-messaging-azure-eventhubs/src/test/java/com/azure/spring/messaging/eventhubs/implementation/support/converter/EventHubsBatchMessageConverterTests.java index 92968d0ba361..6f32ec048df8 100644 --- a/sdk/spring/spring-messaging-azure-eventhubs/src/test/java/com/azure/spring/messaging/eventhubs/implementation/support/converter/EventHubsBatchMessageConverterTests.java +++ b/sdk/spring/spring-messaging-azure-eventhubs/src/test/java/com/azure/spring/messaging/eventhubs/implementation/support/converter/EventHubsBatchMessageConverterTests.java @@ -10,13 +10,13 @@ import com.azure.messaging.eventhubs.models.PartitionContext; import com.azure.spring.messaging.eventhubs.support.EventHubsHeaders; import com.azure.spring.messaging.support.pojo.User; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.springframework.messaging.Message; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ObjectMapper; import java.time.Instant; import java.util.ArrayList; @@ -63,7 +63,7 @@ void beforeEach() { } @Test - public void receivePayloadAsByte() throws JsonProcessingException { + public void receivePayloadAsByte() throws JacksonException { List events = setupEventDataListByPayload(Arrays.asList(payloadBytes1, payloadBytes2)); EventBatchContext eventBatchContext = new EventBatchContext(partitionContext, events, checkpointStore, lastEnqueuedEventProperties); @@ -73,7 +73,7 @@ public void receivePayloadAsByte() throws JsonProcessingException { } @Test - public void receivePayloadAsString() throws JsonProcessingException { + public void receivePayloadAsString() throws JacksonException { List events = setupEventDataListByPayload(Arrays.asList(payload1.getBytes(UTF_8), payload2.getBytes(UTF_8))); EventBatchContext eventBatchContext = new EventBatchContext(partitionContext, events, checkpointStore, lastEnqueuedEventProperties); @@ -83,7 +83,7 @@ public void receivePayloadAsString() throws JsonProcessingException { } @Test - public void receivePayloadAsPojo() throws JsonProcessingException { + public void receivePayloadAsPojo() throws JacksonException { List events = setupEventDataListByPayload(Arrays.asList(objectMapper.writeValueAsBytes(payloadPojo1), objectMapper.writeValueAsBytes(payloadPojo2))); EventBatchContext eventBatchContext = new EventBatchContext(partitionContext, events, checkpointStore, lastEnqueuedEventProperties); @@ -98,7 +98,7 @@ public void receivePayloadAsPojo() throws JsonProcessingException { @Test - public void testNativeHeadersFromEventBatchContext() throws JsonProcessingException { + public void testNativeHeadersFromEventBatchContext() throws JacksonException { List events = setupEventDataListByPayload(Arrays.asList(payloadBytes1, payloadBytes2)); String nativeHeadersString = "{\"spanId\":[\"spanId-1\", \"spanId-2\"],\"spanTraceId\":[\"spanTraceId-1\", \"spanTraceId-2\"]}"; events.forEach(eventData -> eventData.getProperties().put(NATIVE_HEADERS, nativeHeadersString)); @@ -112,7 +112,7 @@ public void testNativeHeadersFromEventBatchContext() throws JsonProcessingExcept } @Test - public void testEventBatchContextHeaders() throws JsonProcessingException { + public void testEventBatchContextHeaders() throws JacksonException { List events = setupEventDataListByPayload(Arrays.asList(payloadBytes1, payloadBytes2)); EventBatchContext eventBatchContext = new EventBatchContext(partitionContext, events, checkpointStore, lastEnqueuedEventProperties); @@ -140,7 +140,7 @@ public void testEventBatchContextHeaders() throws JsonProcessingException { headers.forEach(map -> assertEquals(map.get(headerProperties), headerProperties)); } - private List setupEventDataListByPayload(List payloads) throws JsonProcessingException { + private List setupEventDataListByPayload(List payloads) throws JacksonException { List events = new ArrayList<>(); payloads.forEach(payload -> { EventData event = new EventData(payload); diff --git a/sdk/spring/spring-messaging-azure-servicebus/src/main/java/com/azure/spring/messaging/servicebus/implementation/support/converter/ServiceBusMessageConverter.java b/sdk/spring/spring-messaging-azure-servicebus/src/main/java/com/azure/spring/messaging/servicebus/implementation/support/converter/ServiceBusMessageConverter.java index 411f6fbebff0..d2f59af8acb7 100644 --- a/sdk/spring/spring-messaging-azure-servicebus/src/main/java/com/azure/spring/messaging/servicebus/implementation/support/converter/ServiceBusMessageConverter.java +++ b/sdk/spring/spring-messaging-azure-servicebus/src/main/java/com/azure/spring/messaging/servicebus/implementation/support/converter/ServiceBusMessageConverter.java @@ -10,12 +10,12 @@ import com.azure.spring.messaging.AzureHeaders; import com.azure.spring.messaging.implementation.converter.AbstractJacksonAzureMessageConverter; import com.azure.spring.messaging.servicebus.support.ServiceBusMessageHeaders; -import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.messaging.MessageHeaders; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; +import tools.jackson.databind.ObjectMapper; import java.time.Duration; import java.time.Instant; diff --git a/sdk/spring/spring-messaging-azure-storage-queue/src/main/java/com/azure/spring/messaging/storage/queue/implementation/support/converter/StorageQueueMessageConverter.java b/sdk/spring/spring-messaging-azure-storage-queue/src/main/java/com/azure/spring/messaging/storage/queue/implementation/support/converter/StorageQueueMessageConverter.java index 071f94d0d9e0..eb13117b9a75 100644 --- a/sdk/spring/spring-messaging-azure-storage-queue/src/main/java/com/azure/spring/messaging/storage/queue/implementation/support/converter/StorageQueueMessageConverter.java +++ b/sdk/spring/spring-messaging-azure-storage-queue/src/main/java/com/azure/spring/messaging/storage/queue/implementation/support/converter/StorageQueueMessageConverter.java @@ -6,7 +6,7 @@ import com.azure.core.util.BinaryData; import com.azure.spring.messaging.implementation.converter.AbstractJacksonAzureMessageConverter; import com.azure.storage.queue.models.QueueMessageItem; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import java.nio.charset.StandardCharsets; diff --git a/sdk/spring/spring-messaging-azure/pom.xml b/sdk/spring/spring-messaging-azure/pom.xml index 447d6ab144f9..7e5067774f1f 100644 --- a/sdk/spring/spring-messaging-azure/pom.xml +++ b/sdk/spring/spring-messaging-azure/pom.xml @@ -49,9 +49,9 @@ 7.0.8 - com.fasterxml.jackson.core + tools.jackson.core jackson-databind - 2.21.4 + 3.1.4 com.fasterxml.jackson.core @@ -174,7 +174,7 @@ org.springframework:spring-tx:[7.0.8] org.springframework.retry:spring-retry:[2.0.13] com.fasterxml.jackson.core:jackson-annotations:[2.21] - com.fasterxml.jackson.core:jackson-databind:[2.21.4] + tools.jackson.core:jackson-databind:[3.1.4] diff --git a/sdk/spring/spring-messaging-azure/src/main/java/com/azure/spring/messaging/implementation/converter/AbstractJacksonAzureMessageConverter.java b/sdk/spring/spring-messaging-azure/src/main/java/com/azure/spring/messaging/implementation/converter/AbstractJacksonAzureMessageConverter.java index 6e0d806f3442..1d5037dac751 100644 --- a/sdk/spring/spring-messaging-azure/src/main/java/com/azure/spring/messaging/implementation/converter/AbstractJacksonAzureMessageConverter.java +++ b/sdk/spring/spring-messaging-azure/src/main/java/com/azure/spring/messaging/implementation/converter/AbstractJacksonAzureMessageConverter.java @@ -5,15 +5,14 @@ import com.azure.spring.messaging.converter.AzureMessageConverter; import com.azure.spring.messaging.converter.ConversionException; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.lang.NonNull; import org.springframework.messaging.Message; import org.springframework.messaging.MessageHeaders; import org.springframework.messaging.support.MessageBuilder; import org.springframework.util.Assert; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ObjectMapper; -import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.HashMap; @@ -41,7 +40,7 @@ public abstract class AbstractJacksonAzureMessageConverter implements Azur protected byte[] toPayload(Object object) { try { return getObjectMapper().writeValueAsBytes(object); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new ConversionException("Failed to write JSON: " + object, e); } } @@ -58,7 +57,7 @@ protected byte[] toPayload(Object object) { protected U fromPayload(Object payload, Class payloadType) { try { return getObjectMapper().readerFor(payloadType).readValue((byte[]) payload); - } catch (IOException e) { + } catch (JacksonException e) { throw new ConversionException("Failed to read JSON: " + Arrays.toString((byte[]) payload), e); } } diff --git a/sdk/spring/spring-messaging-azure/src/main/java/com/azure/spring/messaging/implementation/converter/ObjectMapperHolder.java b/sdk/spring/spring-messaging-azure/src/main/java/com/azure/spring/messaging/implementation/converter/ObjectMapperHolder.java index 64ef471536d8..18dbb7f5cae3 100644 --- a/sdk/spring/spring-messaging-azure/src/main/java/com/azure/spring/messaging/implementation/converter/ObjectMapperHolder.java +++ b/sdk/spring/spring-messaging-azure/src/main/java/com/azure/spring/messaging/implementation/converter/ObjectMapperHolder.java @@ -3,7 +3,7 @@ package com.azure.spring.messaging.implementation.converter; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; public final class ObjectMapperHolder { From 682ee1ffa7ad0da2b9c558f2e6986910e2fb448f Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Thu, 18 Jun 2026 15:30:34 +0800 Subject: [PATCH 2/5] Remove unused Jackson external_dependencies.txt entries Drop springboot4_com.fasterxml.jackson.core:jackson-databind and springboot4_tools.jackson.core:jackson-core, which are no longer referenced after the Jackson 3 migration. --- eng/versioning/external_dependencies.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/eng/versioning/external_dependencies.txt b/eng/versioning/external_dependencies.txt index d2a2734ef5e9..824fcb55c273 100644 --- a/eng/versioning/external_dependencies.txt +++ b/eng/versioning/external_dependencies.txt @@ -294,7 +294,6 @@ storage_com.microsoft.azure:azure-storage;8.6.6 # sdk\spring\pom.xml modules springboot4_com.diffplug.spotless:spotless-maven-plugin;2.30.0 springboot4_com.fasterxml.jackson.core:jackson-annotations;2.21 -springboot4_com.fasterxml.jackson.core:jackson-databind;2.21.4 springboot4_com.fasterxml.jackson.datatype:jackson-datatype-jdk8;2.21.4 springboot4_com.fasterxml.jackson.module:jackson-module-parameter-names;2.21.4 springboot4_com.github.spotbugs:spotbugs-maven-plugin;4.8.2.0 @@ -388,7 +387,6 @@ springboot4_org.springframework:spring-web;7.0.8 springboot4_org.springframework:spring-webmvc;7.0.8 springboot4_org.testcontainers:testcontainers-junit-jupiter;2.0.5 springboot4_org.testcontainers:testcontainers-azure;2.0.5 -springboot4_tools.jackson.core:jackson-core;3.1.4 springboot4_tools.jackson.core:jackson-databind;3.1.4 springboot4_jakarta.annotation:jakarta.annotation-api;3.0.0 springboot4_ch.qos.logback:logback-classic;1.5.34 From d4613a9f155fa62ff797c5073b0e9096dbec1763 Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Thu, 18 Jun 2026 15:34:35 +0800 Subject: [PATCH 3/5] Remove redundant throws JacksonException in EventHubsBatchMessageConverterTests JacksonException is unchecked in Jackson 3, so the throws clauses (and the now-unused import) are redundant. Addresses Copilot review feedback. --- .../EventHubsBatchMessageConverterTests.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/sdk/spring/spring-messaging-azure-eventhubs/src/test/java/com/azure/spring/messaging/eventhubs/implementation/support/converter/EventHubsBatchMessageConverterTests.java b/sdk/spring/spring-messaging-azure-eventhubs/src/test/java/com/azure/spring/messaging/eventhubs/implementation/support/converter/EventHubsBatchMessageConverterTests.java index 6f32ec048df8..b3a686437c33 100644 --- a/sdk/spring/spring-messaging-azure-eventhubs/src/test/java/com/azure/spring/messaging/eventhubs/implementation/support/converter/EventHubsBatchMessageConverterTests.java +++ b/sdk/spring/spring-messaging-azure-eventhubs/src/test/java/com/azure/spring/messaging/eventhubs/implementation/support/converter/EventHubsBatchMessageConverterTests.java @@ -15,7 +15,6 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.springframework.messaging.Message; -import tools.jackson.core.JacksonException; import tools.jackson.databind.ObjectMapper; import java.time.Instant; @@ -63,7 +62,7 @@ void beforeEach() { } @Test - public void receivePayloadAsByte() throws JacksonException { + public void receivePayloadAsByte() { List events = setupEventDataListByPayload(Arrays.asList(payloadBytes1, payloadBytes2)); EventBatchContext eventBatchContext = new EventBatchContext(partitionContext, events, checkpointStore, lastEnqueuedEventProperties); @@ -73,7 +72,7 @@ public void receivePayloadAsByte() throws JacksonException { } @Test - public void receivePayloadAsString() throws JacksonException { + public void receivePayloadAsString() { List events = setupEventDataListByPayload(Arrays.asList(payload1.getBytes(UTF_8), payload2.getBytes(UTF_8))); EventBatchContext eventBatchContext = new EventBatchContext(partitionContext, events, checkpointStore, lastEnqueuedEventProperties); @@ -83,7 +82,7 @@ public void receivePayloadAsString() throws JacksonException { } @Test - public void receivePayloadAsPojo() throws JacksonException { + public void receivePayloadAsPojo() { List events = setupEventDataListByPayload(Arrays.asList(objectMapper.writeValueAsBytes(payloadPojo1), objectMapper.writeValueAsBytes(payloadPojo2))); EventBatchContext eventBatchContext = new EventBatchContext(partitionContext, events, checkpointStore, lastEnqueuedEventProperties); @@ -98,7 +97,7 @@ public void receivePayloadAsPojo() throws JacksonException { @Test - public void testNativeHeadersFromEventBatchContext() throws JacksonException { + public void testNativeHeadersFromEventBatchContext() { List events = setupEventDataListByPayload(Arrays.asList(payloadBytes1, payloadBytes2)); String nativeHeadersString = "{\"spanId\":[\"spanId-1\", \"spanId-2\"],\"spanTraceId\":[\"spanTraceId-1\", \"spanTraceId-2\"]}"; events.forEach(eventData -> eventData.getProperties().put(NATIVE_HEADERS, nativeHeadersString)); @@ -112,7 +111,7 @@ public void testNativeHeadersFromEventBatchContext() throws JacksonException { } @Test - public void testEventBatchContextHeaders() throws JacksonException { + public void testEventBatchContextHeaders() { List events = setupEventDataListByPayload(Arrays.asList(payloadBytes1, payloadBytes2)); EventBatchContext eventBatchContext = new EventBatchContext(partitionContext, events, checkpointStore, lastEnqueuedEventProperties); @@ -140,7 +139,7 @@ public void testEventBatchContextHeaders() throws JacksonException { headers.forEach(map -> assertEquals(map.get(headerProperties), headerProperties)); } - private List setupEventDataListByPayload(List payloads) throws JacksonException { + private List setupEventDataListByPayload(List payloads) { List events = new ArrayList<>(); payloads.forEach(payload -> { EventData event = new EventData(payload); From 8c45df1e004402afd14b764bc18e80d3a4e93c0e Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Thu, 18 Jun 2026 16:05:19 +0800 Subject: [PATCH 4/5] Fix Jackson 3 NoClassDefFoundError in spring-integration-azure-servicebus Exclude the Jackson 2.18 jackson-annotations brought transitively by the azure-core-serializer-json-jackson test dependency. It lacks com.fasterxml.jackson.annotation.JsonSerializeAs (required by tools.jackson.databind 3.x) and won dependency mediation on the test classpath, breaking ObjectMapperHolder/ServiceBusTemplate initialization. After exclusion, the Jackson 3-compatible jackson-annotations 2.21 from spring-messaging-azure is used. --- sdk/spring/spring-integration-azure-servicebus/pom.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sdk/spring/spring-integration-azure-servicebus/pom.xml b/sdk/spring/spring-integration-azure-servicebus/pom.xml index 532e9d16c914..bd6846f21889 100644 --- a/sdk/spring/spring-integration-azure-servicebus/pom.xml +++ b/sdk/spring/spring-integration-azure-servicebus/pom.xml @@ -67,6 +67,15 @@ azure-core-serializer-json-jackson 1.6.5 test + + + + com.fasterxml.jackson.core + jackson-annotations + + org.mockito From 21b82c68c93d62a2d1feafa981077af3fc895cf5 Mon Sep 17 00:00:00 2001 From: Rujun Chen Date: Thu, 18 Jun 2026 16:17:46 +0800 Subject: [PATCH 5/5] Allowlist TargetingFilter.OBJECT_MAPPER Jackson 3 type change in RevApi The protected static OBJECT_MAPPER field type changed from com.fasterxml.jackson.databind.ObjectMapper to tools.jackson.databind.ObjectMapper as part of the Jackson 2->3 migration for Spring Boot 4. Add a RevApi difference allowlist entry with justification for this intentional breaking change. --- eng/lintingconfigs/revapi/track2/revapi.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/eng/lintingconfigs/revapi/track2/revapi.json b/eng/lintingconfigs/revapi/track2/revapi.json index 8f80314039f4..42b30b374e36 100644 --- a/eng/lintingconfigs/revapi/track2/revapi.json +++ b/eng/lintingconfigs/revapi/track2/revapi.json @@ -369,6 +369,12 @@ "new" : "parameter void com.azure.spring.integration.core.handler.DefaultMessageHandler::setSendCallback(===java.util.function.BiConsumer===)", "justification" : "Replace deprecated parameterType" }, + { + "code" : "java.field.typeChanged", + "old" : "field com.azure.spring.cloud.feature.management.filters.TargetingFilter.OBJECT_MAPPER", + "new" : "field com.azure.spring.cloud.feature.management.filters.TargetingFilter.OBJECT_MAPPER", + "justification" : "Jackson 2 to Jackson 3 migration to align with Spring Boot 4: the field type changed from com.fasterxml.jackson.databind.ObjectMapper to tools.jackson.databind.ObjectMapper. This is an intentional breaking change for these beta Spring libraries (see issue 49538)." + }, { "code": "java.method.numberOfParametersChanged", "old": {