Introducing Jackson 3 support in Spring

Engineering | Sébastien Deleuze | October 07, 2025 | ...

This is a new blog post in the Road to GA series, this time sharing more details on the new Jackson 3 support, just a few days after Jackson 3.0.0 GA release, about to be introduced in Spring Boot 4 and related Spring portfolio projects.

Jackson is by far the most used JSON library on the JVM, and the introduction of the Jackson 3 support in Spring is the opportunity for us to provide additional enhancements, as a follow-up of the popular Jackson integration improvements in Spring that I announced more than 10 years ago!

Close collaboration between Spring and Jackson teams

When the Spring team works on leveraging new versions of popular open source libraries, while it may not be obvious, a significant part of the work is sometimes collaborating with the maintainers on refinements that will benefit the wider community.

Jackson 3 is a great illustration of that and I would like to thank Tatu Saloranta (the Jackson project lead) for his willingness to take our feedback into account during the release candidate phase - which has allowed the following refinements:

Status of the Jackson support as of Spring Boot 4

The general principle is that, as of Spring Boot 4 and Spring Framework 7, the Spring portfolio is:

  • Introducing Jackson 3 support
  • Deprecating the Jackson 2 support for eventual removal
  • Switching the default Jackson version enabled (classpath detection) to Jackson 3

Main exception to this is Spring AI which intends to introduce Jackson 3 support in its 2.0 release in the first half of 2026.

More specifically, Spring Boot 4 is:

  • Providing dependency management for both Jackson 2 and 3
  • Performing auto-configuration only for Jackson 3
  • Using Jackson 3 in its spring-boot-starter-json and spring-boot-starter-jackson starter dependencies

Applications migrating to Spring Boot 4 are encouraged to migrate to Jackson 3, even if it’s still possible to use Jackson 2 with Spring Boot 4 (see related section below). Transitive dependencies still depending on Jackson 2 remain supported and will benefit from the Jackson 2 dependency management.

Migrating to Jackson 3

This section focuses on the most important migration steps for typical Spring Boot applications, see the Jackson 3 migration guide for more details on other aspects. Related Open Rewrite recipes can help to automate some of those changes, and Spring Application Advisor will provide the most comprehensive option for migrating your Spring Boot application incrementally.

Update packages

The first breaking change you will encounter when upgrading is probably the Jackson package (and dependency groupID) change from com.fasterxml.jackson to tools.jackson except for jackson-annotations which remains unchanged for backward-compatibility reasons.

Adapt to the new default settings

Jackson 3 has changed some default settings compared to Jackson 2, so you should either adapt your tests accordingly (recommended when you can), or customize Jackson 3 configuration to restore some of the previous defaults.

The changes most likely to break you tests are the following:

  • If you are comparing Jackson serialization with raw strings in your tests, you will likely be impacted by MapperFeature.SORT_PROPERTIES_ALPHABETICALLY now set to true.
  • SerializationFeature.WRITE_DATES_AS_TIMESTAMPS now known as DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS has been changed to false to serialize dates as ISO-8601 strings.

If you prefer at least initially keep using default settings as close as possible as Jackson 2, you can use:

@Bean
JsonMapperBuilderCustomizer jacksonCustomizer() {
    return builder -> builder.configureForJackson2();
}

Jackson modules

Some former Jackson 2 modules are now built in Jackson 3, like the parameter-names or datatype-jsr310 ones. Other modules previously enabled via the Jackson2ObjectMapperBuilder are now discovered automatically via the JDK service loader facility for the converters and codecs provided with Spring Framework.

It is also of course possible to configure custom ones via JsonMapper.Builder.

From ObjectMapper to JsonMapper

Jackson 3 introduces a lot of changes and enhancements, but from a Spring perspective one of the most important ones to understand and embrace is the switch from a mutable ObjectMapper in Jackson 2 to an immutable JsonMapper in Jackson 3.

JsonMapper, which extends ObjectMapper, is specific to the JSON format, following a similar pattern than other formats (XmlMapper, YAMLMapper, SmileMapper, etc.) and Spring support has been updated to use this format specific variant, following Jackson 3 best practices.

Also with Jackson and Spring defaults mostly aligned, and the introduction of a first class JsonMapper.Builder, Spring Framework does not provide an equivalent for Jackson2ObjectMapperBuilder, you should just use the Jackson builder.

For example, with Spring Boot 3 and its Jackson 2 support, the programmatic equivalent of spring.jackson.serialization.indent-output=true was:

@Bean
public Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() {
    return builder -> builder.indentOutput(true);
}

With Spring Boot 4 and its Jackson 3 support, it is:

@Bean
JsonMapperBuilderCustomizer jacksonCustomizer() {
    return builder -> builder.enable(SerializationFeature.INDENT_OUTPUT);
}

Goodbye MappingJacksonValue

The now deprecated MappingJackson2HttpMessageConverter was extending GenericHttpMessageConverter which does not allow to pass properly additional serialization information like the serialization view or FilterProvider, hence the need for a MappingJacksonValue wrapper.

For example, let say we are annotating a User record with @JsonView(Summary.class) to identify a subset of its components to serialize or deserialize:

public record User(
    @JsonView(Summary.class) String firstname,
    @JsonView(Summary.class) String lastname,
    LocalDate birthdate,
    @JsonView(Summary.class) String email,
    String address,
    int postalCode,
    String city,
    String country) {
}

With Spring Framework 6 and before, on client side you had to use a MappingJacksonValue wrapper to specify the Summary JSON view should be used.

var user = new User("Marcel", "Martin", LocalDate.of(1971, 7, 12),
    "[email protected]", "1234 rue Gambetta", 69002, "Lyon", "France");
var jacksonValue = new MappingJacksonValue(user);
jacksonValue.setSerializationView(Summary.class);
var response = this.restTemplate.postForObject("http://localhost:8080/create", jacksonValue, String.class);

This allows to serialize only the record components annotated with @JsonView(Summary.class):

{
  "firstname" : "Marcel",
  "lastname" : "Martin",
  "email" : "[email protected]"
}

As of Spring Framework 7, you can leverage the fact that the new JacksonJsonHttpMessageConverter based on Jackson 3 is implementing SmartHttpMessageConverter which supports serialization hints, so you can write instead:

var user = new User("Marcel", "Martin", LocalDate.of(1971, 7, 12),
    "[email protected]", "1234 rue Gambetta", 69002, "Lyon", "France");
var response = this.restClient.post().uri("http://localhost:8080/create")
    .hint(JsonView.class.getName(), Summary.class).body(user)
    .retrieve().body(String.class);

No more mutable wrapper, just optional hints.

Keep using Jackson 2 support temporarily

Applications migrating to Spring Boot 4 are encouraged to migrate to Jackson 3 but can continue to use Jackson 2 or even use Jackson 2 and 3 at the same time if needed. Just be aware it may require adding Jackson 2 dependencies and some manual configuration.

With Spring Boot 4 and Spring MVC, if you exclude Jackson 3 dependencies and add Jackson 2 ones, the Jackson 2 support will be used by default as it will be detected by WebMvcConfigurationSupport.

If you have both Jackson 2 and Jackson 3 in the classpath, Spring Framework introduces a new org.springframework.http.converter.HttpMessageConverters type and a related Spring Boot 4 customizer which allows to force using Jackson 2 pretty easily:

@Bean
@SuppressWarnings("removal")
public ServerHttpMessageConvertersCustomizer jackson2ServerConvertersCustomizer() {
    return builder -> builder.jsonMessageConverter(new MappingJackson2HttpMessageConverter());
}

Spring Security Jackson 3 support

The related pull-request is not yet merged and still subject to refinements, but it is worth to notice that in addition to introducing Jackson 3 support and deprecating Jackson 2 one, Spring Security 7.0 is going to make its Jackson 3 support safer by disabling default global typing (see this blog post for more background).

Instead, it leverages a PolymorphicTypeValidator where only Spring Security types are allowed by default, and provide the capability for applications to add their own types, for example:

ClassLoader loader = getClass().getClassLoader();
BasicPolymorphicTypeValidator.Builder typeValidatorBuilder = BasicPolymorphicTypeValidator.builder()
    .allowIfSubType(CustomGrantedAuthority.class);
JsonMapper mapper = JsonMapper.builder()
    .addModules(SecurityJacksonModules.getModules(loader, typeValidatorBuilder))
    .build();

Due to the Jackson 3 changes and the disabling of global default typing, Jackson 2 and Jackson 3 serialized data format will be different, but in in order to ease the migration of applications storing Jackson 2 in databases for example, a Jackson 2 compatibility mode is going to be provided in order to allow migrating to Spring Boot 4 and Spring Security 7, while still using the very same Jackson 2 data format with Jackson 3.

Spring Data Jackson 3 support

Spring Data 4.0 ships with full support for Jackson 3 for its core modules. Applications migrating to Spring Data 4 are encouraged to migrate to Jackson 3 but can continue to use Jackson 2 or even use Jackson 2 and 3 at the same time if needed. Just be aware that Jackson 3 ships with a different set of defaults that may require either a migration of your persistent data or updating Jackson 3 defaults to match Jackson 2 settings.

As Spring Data forms a larger set of projects, let's explore each module separately:

Spring Data Commons

Spring Data Commons adding support for Jackson 3 with a fallback to Jackson 2 if only Jackson 2 is on the classpath. This applies mostly to Web support through ProjectingJacksonHttpMessageConverter and SpringDataWebConfiguration.

JacksonResourceReader and JacksonRepositoryPopulatorFactoryBean are Jackson 3-based variants of Jackson2ResourceReader respective Jackson2RepositoryPopulatorFactoryBean.

If you’re using Jackson 2 together with Spring Data’s XML namespace support (<repository:jackson2-populator …>) and you want to migrate to Jackson 3, then you will have to define a JacksonRepositoryPopulatorFactoryBean bean in your Java configuration.

If you happen to use SpringDataJacksonModules, then you want to consider migrating towards SpringDataJackson3Modules for a Jackson 3-based arrangement of your modules.

Spring Data Redis

Spring Data Redis 4.0 ships with JacksonHashMapper, JacksonJsonRedisSerializer, and GenericJacksonJsonRedisSerializer implementations for Jackson 3. When using JacksonObjectReader and JacksonObjectWriter, make sure to retrofit your implementations using Jackson2ObjectReader respective Jackson2ObjectWriter as class naming has been aligned for a consistent scheme.

Spring Data REST

Spring Data REST is essentially a large wrapper around Jackson that doesn't support an operating mode using Jackson 2. If you want to use the new Spring Data REST version then your application must migrate to Jackson 3. Similar goes for Spring HATEOAS as both frameworks make heavy usage of Jackson.

Spring Data Couchbase, Elasticsearch, Drivers

The larger ecosystem is slowly catching up with Jackson 3. Couchbase, Elasticsearch, and some drivers use Jackson 2 internally and will continue doing so. In most cases, Jackson usage within these components doesn't relate to your entities as it is their mechanism for a JSON parser and writer.

Conclusion

Jackson 3 brings strong benefits in terms of security, API, default configuration and capabilities, but it also comes with breaking changes that will require some migration work, the Spring team fully realizes that and has put significant efforts in providing the best possible arrangement and related guidance as well as offering industry leading extended support on the previous version to give you the time to upgrade.

As usual, we are looking for feedback and will do our best to refine our guidance, documentation and answer to your related questions.

Get the Spring newsletter

Stay connected with the Spring newsletter

Subscribe

Get ahead

VMware offers training and certification to turbo-charge your progress.

Learn more

Get support

Tanzu Spring offers support and binaries for OpenJDK™, Spring, and Apache Tomcat® in one simple subscription.

Learn more

Upcoming events

Check out all the upcoming events in the Spring community.

View all