Upgrade sdk/spring to Jackson 3 to align with Spring Boot 4#49550
Upgrade sdk/spring to Jackson 3 to align with Spring Boot 4#49550rujche wants to merge 10 commits into
Conversation
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.
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.
There was a problem hiding this comment.
Pull request overview
This PR migrates the Spring libraries under sdk/spring from Jackson 2 (com.fasterxml.jackson.*) to Jackson 3 (tools.jackson.*) to align with the Spring Boot 4 dependency stack and avoid Jackson 2/3 classpath conflicts (per #49538).
Changes:
- Updated multiple Spring module POMs to depend on
tools.jackson.core:jackson-databind:3.1.4(and updated related enforcer rules / version pins). - Migrated production and test code imports and APIs from
com.fasterxml.jackson.*totools.jackson.*(including JSON node string APIs and exception types). - Updated Spring Boot auto-configuration tests to use Jackson 3 auto-config (
JacksonAutoConfiguration) andJsonMapper-based mapper creation where needed.
Reviewed changes
Copilot reviewed 45 out of 45 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| sdk/spring/spring-messaging-azure/src/main/java/com/azure/spring/messaging/implementation/converter/ObjectMapperHolder.java | Switches ObjectMapper import to Jackson 3 namespace. |
| sdk/spring/spring-messaging-azure/src/main/java/com/azure/spring/messaging/implementation/converter/AbstractJacksonAzureMessageConverter.java | Updates Jackson exception/import usage to Jackson 3 types. |
| sdk/spring/spring-messaging-azure/pom.xml | Replaces Jackson 2 databind dependency/enforcer entry with Jackson 3 coordinates. |
| sdk/spring/spring-messaging-azure-storage-queue/src/main/java/com/azure/spring/messaging/storage/queue/implementation/support/converter/StorageQueueMessageConverter.java | Switches ObjectMapper import to Jackson 3 namespace. |
| sdk/spring/spring-messaging-azure-servicebus/src/main/java/com/azure/spring/messaging/servicebus/implementation/support/converter/ServiceBusMessageConverter.java | Switches ObjectMapper import to Jackson 3 namespace. |
| sdk/spring/spring-messaging-azure-eventhubs/src/test/java/com/azure/spring/messaging/eventhubs/implementation/support/converter/EventHubsBatchMessageConverterTests.java | Migrates test imports/exceptions to Jackson 3. |
| sdk/spring/spring-messaging-azure-eventhubs/src/main/java/com/azure/spring/messaging/eventhubs/implementation/support/converter/EventHubsMessageConverter.java | Switches ObjectMapper import to Jackson 3 namespace. |
| sdk/spring/spring-messaging-azure-eventhubs/src/main/java/com/azure/spring/messaging/eventhubs/implementation/support/converter/EventHubsBatchMessageConverter.java | Switches ObjectMapper import to Jackson 3 namespace. |
| sdk/spring/spring-cloud-azure-feature-management/src/main/java/com/azure/spring/cloud/feature/management/implementation/FeatureManagementProperties.java | Switches ObjectMapper import to Jackson 3 namespace. |
| sdk/spring/spring-cloud-azure-feature-management/src/main/java/com/azure/spring/cloud/feature/management/filters/TimeWindowFilter.java | Migrates mapper/node APIs and adds Jackson 3 databind exception handling. |
| sdk/spring/spring-cloud-azure-feature-management/src/main/java/com/azure/spring/cloud/feature/management/filters/TargetingFilter.java | Switches Jackson imports to Jackson 3 namespace. |
| sdk/spring/spring-cloud-azure-feature-management/pom.xml | Replaces Jackson 2 databind dependency/enforcer entry with Jackson 3 coordinates. |
| sdk/spring/spring-cloud-azure-docker-compose/pom.xml | Replaces Jackson 2 databind dependency/enforcer entry with Jackson 3 coordinates. |
| sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/storage/AzureStorageQueueMessagingAutoConfigurationTests.java | Moves tests to Jackson 3 auto-config and JsonMapper creation. |
| sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusMessagingAutoConfigurationTests.java | Moves tests to Jackson 3 auto-config and JsonMapper creation. |
| sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/eventhubs/AzureEventHubsMessagingAutoConfigurationTests.java | Moves tests to Jackson 3 auto-config and JsonMapper creation. |
| sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/aad/security/graph/GraphClientTest.java | Updates JSON serialization in tests to use Jackson 3 JsonMapper. |
| sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/aad/filter/UserPrincipalMicrosoftGraphTests.java | Migrates test Jackson imports/exceptions to Jackson 3. |
| sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/storage/queue/AzureStorageQueueMessagingAutoConfiguration.java | Switches ObjectMapper import to Jackson 3 namespace. |
| sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusMessagingAutoConfiguration.java | Switches ObjectMapper import to Jackson 3 namespace. |
| sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/eventhubs/AzureEventHubsMessagingAutoConfiguration.java | Switches ObjectMapper import to Jackson 3 namespace. |
| sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/utils/JacksonObjectMapperFactory.java | Switches ObjectMapper import to Jackson 3 namespace. |
| sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/serde/jackson/StdConverters.java | Migrates Jackson node/converter imports to Jackson 3 namespace. |
| sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/serde/jackson/SerializerUtils.java | Migrates Spring Security Jackson modules and mapper usage to Jackson 3. |
| sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/serde/jackson/JsonNodeUtils.java | Updates JsonNode APIs and refactors value conversion to use DeserializationContext. |
| sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/serde/jackson/AadOAuth2ClientJacksonModule.java | Replaces Jackson 2 module implementation with Jackson 3 module API usage. |
| sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/serde/jackson/AadClientRegistrationMixin.java | Switches @JsonDeserialize annotation import to Jackson 3 namespace. |
| sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/serde/jackson/AadClientRegistrationDeserializer.java | Migrates deserializer to Jackson 3 deserializer base type and parsing APIs. |
| sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/aad/filter/AadGraphClient.java | Switches ObjectMapper import to Jackson 3 namespace. |
| sdk/spring/spring-cloud-azure-autoconfigure/pom.xml | Adds Spring Boot Jackson 3 autoconfig artifact and Jackson 3 databind dependency/enforcer entry. |
| sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/TestUtils.java | Updates test JSON node APIs and exception type to Jackson 3. |
| sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParserTest.java | Switches Jackson imports in tests to Jackson 3 namespace. |
| sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/AppConfigurationApplicationSettingPropertySourceTest.java | Removes Jackson 2 mapper usage in tests (imports/strategy). |
| sdk/spring/spring-cloud-azure-appconfiguration-config/src/test/java/com/azure/spring/cloud/appconfiguration/config/implementation/AppConfigurationApplicationSettingPropertySourceSnapshotTest.java | Removes Jackson 2 mapper usage in tests (imports/strategy). |
| sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/JsonConfigurationParser.java | Migrates JSON parsing/iteration APIs and exception types to Jackson 3. |
| sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/FeatureFlagClient.java | Migrates JSON parsing APIs and exception types to Jackson 3. |
| sdk/spring/spring-cloud-azure-appconfiguration-config/src/main/java/com/azure/spring/cloud/appconfiguration/config/implementation/AppConfigurationFeatureManagementPropertySource.java | Switches ObjectMapper/JsonMapper imports to Jackson 3 namespace. |
| sdk/spring/spring-cloud-azure-appconfiguration-config/pom.xml | Adds Jackson 3 databind dependency and updates enforcer entry for Jackson 3. |
| sdk/spring/spring-cloud-azure-appconfiguration-config-web/src/test/java/com/azure/spring/cloud/appconfiguration/config/web/implementation/AppConfigurationEndpointTest.java | Migrates tests to Jackson 3 mapper/node types and removes checked Jackson 2 exceptions. |
| sdk/spring/spring-cloud-azure-appconfiguration-config-web/src/main/java/com/azure/spring/cloud/appconfiguration/config/web/implementation/pushrefresh/AppConfigurationRefreshEndpoint.java | Migrates JsonNode import and string accessor API to Jackson 3. |
| sdk/spring/spring-cloud-azure-appconfiguration-config-web/src/main/java/com/azure/spring/cloud/appconfiguration/config/web/implementation/pushbusrefresh/AppConfigurationBusRefreshEndpoint.java | Migrates JsonNode import and string accessor API to Jackson 3. |
| sdk/spring/spring-cloud-azure-appconfiguration-config-web/src/main/java/com/azure/spring/cloud/appconfiguration/config/web/implementation/AppConfigurationEndpoint.java | Migrates to Jackson 3 JsonMapper and string accessor API updates. |
| sdk/spring/spring-cloud-azure-actuator-autoconfigure/pom.xml | Replaces Jackson 2 databind dependency/enforcer entry with Jackson 3 coordinates. |
| sdk/spring/CHANGELOG.md | Adds release notes entries for the Jackson 3 migration across affected Spring modules. |
| eng/versioning/external_dependencies.txt | Adds Spring Boot 4 spring-boot-jackson and Jackson 3 dependency pins for version management. |
…erterTests JacksonException is unchecked in Jackson 3, so the throws clauses (and the now-unused import) are redundant. Addresses Copilot review feedback.
|
/azp run java - spring - tests |
|
Azure Pipelines successfully started running 1 pipeline(s). |
…ebus 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.
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.
|
/azp run java - spring - tests |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run java - spring - tests |
|
Azure Pipelines successfully started running 1 pipeline(s). |
| @BeforeEach | ||
| public void init() { | ||
| session = Mockito.mockitoSession().initMocks(this).strictness(Strictness.STRICT_STUBS).startMocking(); | ||
| MAPPER.setPropertyNamingStrategy(PropertyNamingStrategies.KEBAB_CASE); |
There was a problem hiding this comment.
This was removed because it had become dead test code in this class. The local MAPPER field and the KEBAB_CASE setup were no longer referenced by any assertion or test path after the Jackson 3 migration, so keeping them only added unused imports/state without affecting behavior.
| // 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()); |
There was a problem hiding this comment.
I verified this before keeping the removal. SerializerUtilsTests.serializeAndDeserializeTest() round-trips OAuth2AuthorizedClient, including the OAuth2AccessToken issuedAt and expiresAt Instant fields, and it passes without explicitly registering JavaTimeModule. In this mapper setup, the Spring Security Jackson modules cover the types we serialize here, so the extra module was redundant for this code path.
There was a problem hiding this comment.
Follow-up after validating the full SerializerUtils path: I was also able to remove the now-redundant custom AadOAuth2ClientJacksonModule/AadClientRegistration* helpers, and then verified that CoreJacksonModule is not required for this code path either. OAuth2ClientJacksonModule remains required, but the serializer and session repository tests still pass after removing the custom helpers and CoreJacksonModule. Updated in 9c7f63c.
| @@ -89,15 +89,17 @@ void connectionInfoAndCheckpointStoreProvidedShouldConfigure() { | |||
|
|
|||
| @Test | |||
| @SuppressWarnings("removal") | |||
There was a problem hiding this comment.
please help confirm if this annotation is still needed
There was a problem hiding this comment.
Yes, the remaining @SuppressWarnings("removal") annotations in these messaging converter tests were stale Jackson 2 migration leftovers. I removed them in 7d92a42 and re-ran the targeted storage/servicebus/eventhubs auto-config tests successfully after the cleanup.
| private static final JsonMapper OBJECT_MAPPER; | ||
| private static final TypeReference<Map<String, OAuth2AuthorizedClient>> TYPE_REFERENCE = new TypeReference<>() { }; | ||
|
|
Summary
Migrate Jackson 2 (
com.fasterxml.jackson.databind/com.fasterxml.jackson.core) to Jackson 3 (tools.jackson) across 10sdk/springmodules to align with Spring Boot 4.Changes
com.fasterxml.jackson.core:jackson-databinddependency (and Maven enforcer<includes>allowlist entries) totools.jackson.core:jackson-databind:3.1.4in affected POMs.com.fasterxml.jackson.databind.*->tools.jackson.databind.*,com.fasterxml.jackson.core.*->tools.jackson.core.*;new ObjectMapper()->JsonMapper.builder().build();asText()/isTextual()/textValue()->asString()/isString()/stringValue(); checked Jackson exceptions -> uncheckedtools.jackson.core.JacksonException;JsonDeserializer->ValueDeserializer;setMixInAnnotations->setMixIn.spring-cloud-azure-autoconfigure: removed the now-redundant customAadOAuth2ClientJacksonModule/AadClientRegistration*helpers after validating upstream Jackson 3 Spring Security support; retainedOAuth2ClientJacksonModuleas the required module for theOAuth2AuthorizedClientserialization path.spring-boot-jackson(Jackson 3 autoconfig) added alongside the retainedspring-boot-jackson2compat module.com.fasterxml.jackson.annotation.*) are intentionally retained (unchanged in Jackson 3).jackson-annotationsalignment where needed to avoid test classpath conflicts (2.18.7vs2.21) causingNoClassDefFoundError: com/fasterxml/jackson/annotation/JsonSerializeAs.TargetingFilter.OBJECT_MAPPERfield type change (com.fasterxml.jackson.databind.ObjectMapper->tools.jackson.databind.ObjectMapper).sdk/spring/CHANGELOG.mdfor all 10 affected modules.Out of scope
Cosmos (
azure-spring-data-cosmosand the Spring Cloud Azure Cosmos starter) is not migrated to Jackson 3 in this PR. It cannot be migrated in isolation because:azure-spring-data-cosmosdepends onazure-cosmos, andazure-cosmosexposes Jackson 2 types (e.g.com.fasterxml.jackson.databind.JsonNodeinCosmosItemSerializer,CosmosItemResponse, and mostcom.azure.cosmos.models.*classes) as part of its public API. About 65 public classes importcom.fasterxml.jackson.JsonNodeis part of the public contract, movingazure-cosmosto Jackson 3 is a breaking API change that cascades to every dependent module undersdk/cosmos(azure-cosmos-encryption,azure-cosmos-spark_3and variants,azure-cosmos-kafka-connect,azure-cosmos-benchmark,azure-cosmos-tests, ...) — roughly 440+ source files reference Jackson 2 across the tree.azure-cosmosis a GA data-plane library, so such a breaking change requires separate API review and a coordinated, multi-module effort.This follow-up work is tracked in #49551.
Verification
spring-cloud-azure-autoconfiguremessaging auto-config suites (storage queue / service bus / event hubs).SerializerUtilsTestsandJacksonHttpSessionOAuth2AuthorizedClientRepositoryTest, including the cleanup that removed the custom Aad Jackson helper classes andCoreJacksonModule.Resolves #49538