eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – All Access – NPI EA (cat= Spring)
announcement - icon

All Access is finally out, with all of my Spring courses. Learn JUnit is out as well, and Learn Maven is coming fast. And, of course, quite a bit more affordable. Finally.

>> GET THE COURSE
Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (cat=Spring Boot)
announcement - icon

Refactor Java code safely — and automatically — with OpenRewrite.

Refactoring big codebases by hand is slow, risky, and easy to put off. That’s where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.

Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions — one for newcomers and one for experienced users. You’ll see how recipes work, how to apply them across projects, and how to modernize code with confidence.

Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.

Course – LJB – NPI EA (cat = Core Java)
announcement - icon

Code your way through and build up a solid, practical foundation of Java:

>> Learn Java Basics

eBook – Jackson – NPI (cat=Jackson)
announcement - icon

Jackson and JSON in Java, finally learn with a coding-first approach:

>> Download the eBook

1. Overview

Jackson has been the most popular JSON processing library in the Java ecosystem for over a decade. After years of incremental updates in the 2.x line, the release of Jackson 3.0 introduces a major architectural overhaul designed to address long-standing technical debt and modernize its API.

In this tutorial, we’ll explore key changes in Jackson 3, how they impact our existing codebases, and the steps required to migrate from the 2.x line.

2. Technical Prerequisites and Migration Path

Let’s review the foundational changes in Jackson 3, including minimum requirements and the necessary steps to prepare our project for migration.

2.1. Java 17 Baseline

Jackson 3.0 raises its minimum supported JDK version from Java 8 to Java 17. This allows Jackson to natively use modern Java language features, such as Java Records or pattern matching.

Before migrating to Jackson 3.0, we should ensure that our project meets this requirement. If not, we must consider upgrading the Java version in our project or remaining on the Jackson 2.x line.

2.2. Artifacts and GroupId

The new major Jackson version introduces a completely new groupId for its artifacts – tools.jackson.core, replacing com.fasterxml.jackson.core. This change allows Jackson 2.x and 3.x to coexist on the classpath in parallel during gradual migrations.

To install the new version of the library, we add it to our pom.xml:

<dependency> 
    <groupId>tools.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>3.2.1</version>
</dependency>

Alternatively, if we want to add a dedicated mapper for another format, such as XML, we need to include its specific module:

<dependency>
    <groupId>tools.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>3.2.1</version>
</dependency>

For these format-specific modules, the group is tools.jackson.dataformat. It’s also worth noting that the jackson-annotations dependency still remains under the old com.fasterxml.jackson.core group. This exception ensures that our core domain models with Jackson annotations do not require modifications when upgrading.

2.3. Package Name Changes

Because of the artifacts groupId change, the base Java package has also shifted from com.fasterxml.jackson to tools.jackson. When migrating projects, we need to update our import statements:

// Remove Old Jackson 2.x imports
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;

// Use New Jackson 3.x imports
import tools.jackson.databind.ObjectMapper;
import tools.jackson.databind.json.JsonMapper;
import tools.jackson.databind.JsonNode;

2.4. Android Compatibility

Because Jackson 3 relies entirely on Java 17, Android projects must be properly configured to support these language features.

Android developers should to target API level 34 (Android 14) or enable core library desugaring in their build configuration to use Jackson 3.

2.5. Removal of Deprecated Methods

As part of the major version bump, Jackson 3 removes all classes, methods, and configurations that had the @Deprecated annotation in the 2.x line. If our current codebase uses any legacy methods, we must replace them with 3.x alternatives before the migration.

Now, let’s move on to specific functional changes in Jackson 3.

3. Immutable ObjectMapper and the Builder Pattern

In previous versions, ObjectMapper instances were mutable. By modifying configurations or registered modules on an active mapper after initialization, we risked running into thread-safety issues, such as race conditions when concurrent threads tried to read and alter the mapper’s state simultaneously.

Jackson 3 solves this by enforcing strict immutability for its mappers. It removes direct configuration methods on ObjectMapper. Instead, we use the builder pattern and format-specific builders to configure our mappers before instantiation.

3.1. Building a JsonMapper

Let’s see how to construct and configure a JsonMapper using the available API:

JsonMapper mapper = JsonMapper.builder()
  .enable(SerializationFeature.INDENT_OUTPUT)
  .disable(JsonWriteFeature.ESCAPE_NON_ASCII)
  .configure(DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS, false)
  .build();

Here, we initialize a builder for the JSON format. We enable pretty-printing, disable the escaping of non-ASCII characters, and tell Jackson not to serialize dates as numeric timestamps.

Jackson uses Java enums as sets of feature toggles to control parsing, serialization, and mapping behavior. We can find general configuration options in the SerializationFeature, DeserializationFeature, and MapperFeature enums. For format- or type-specific requirements, Jackson provides dedicated enums such as JsonWriteFeature (for JSON generation) and DateTimeFeature (for date handling).

3.2. Copying Mappers

If we need a slightly modified version of an existing mapper, we can use the rebuild() method:

JsonMapper prettyMapper = mapper.rebuild()
  .enable(SerializationFeature.INDENT_OUTPUT)
  .build();

Note that prettyMapper and mapper from the previous snippet are completely different objects. The rebuild() method copies the internal configuration of the original mapper into a new builder, allowing us to spawn a new instance with slight modifications. Because the mappers are immutable, this operation is entirely thread-safe and won’t affect the original mapper.

3.3. Support for Alternative Data Formats

If our project requires a different data format, we simply switch to the corresponding format-specific builder. For example, we can configure an XmlMapper for XML or a YAMLMapper for YAML using their respective builders:

XmlMapper xmlMapper = XmlMapper.builder()
  .enable(SerializationFeature.INDENT_OUTPUT)
  .build();

YAMLMapper yamlMapper = YAMLMapper.builder()
  .disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER)
  .build();

4. Unchecked Exceptions

One of the biggest readability issues in Jackson 2.x was dealing with the checked JsonProcessingException and IOException during serialization and deserialization. Supporting them inside Java Streams or lambda expressions often led to verbose try-catch blocks or custom wrapper utilities.

In Jackson 3, JacksonException replaces JsonProcessingException as the root exception, and it now extends RuntimeException:

List<User> users = jsonPayloads.stream()
  .map(json -> mapper.readValue(json, User.class)) // No try-catch needed!
  .toList();

This change significantly cleans up our stream operations. Because the exception is unchecked, the compiler no longer forces us to handle it immediately. We can omit the clutter of try-catch blocks within our lambdas, resulting in much cleaner code.

5. Built-in Java 8+ Features

Historically, to properly handle Java 8 features like java.time classes, java.util.Optional, or constructor parameter name detection, we had to explicitly include and register three separate modules: jackson-datatype-jsr310, jackson-datatype-jdk8, and jackson-module-parameter-names.

Since Jackson 3 targets Java 17, these three modules are now integrated into jackson-databind. We can serialize and deserialize LocalDateTime and Optional properties immediately upon creating a new mapper:

public record Event(String title, Optional<String> description, LocalDateTime eventDate) {}

// ...

Event event = new Event("Tech Talk", Optional.of("Jackson 3 overview"), LocalDateTime.now());
JsonMapper mapper = JsonMapper.builder().build();    
String json = mapper.writeValueAsString(event);
Event deserialized = mapper.readValue(json, Event.class);

This native support significantly simplifies the codebase when working with Java 8+ types, as it requires no additional configuration.

6. Configuration Defaults and Behavioral Changes

Jackson 3 changes several default settings to reflect modern development practices and community feedback. A full list of changes can be found in the official documentation. We describe the most impactful ones.

6.1. FAIL_ON_UNKNOWN_PROPERTIES Defaults to false

In Jackson 2.x, encountering unknown JSON fields during deserialization threw an UnrecognizedPropertyException by default unless we explicitly disabled it on the mapper.

In Jackson 3.0, DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES defaults to false. Jackson safely ignores unrecognized fields in incoming JSON payloads unless we explicitly set this flag to true. Let’s verify this:

record User(String name) {}

// ...

JsonMapper mapper = JsonMapper.builder().build();
// The JSON contains "unknownField" which is not present in the User class
String json = "{\"name\":\"Alice\", \"unknownField\":\"ignored_value\"}";
    
// This executes without throwing an exception
User user = mapper.readValue(json, User.class);

In some cases such as strict API validations, it may be necessary to throw an exception when encountering an unknown field. To achieve this, we reenable the feature on the builder:

JsonMapper strictMapper = JsonMapper.builder()
    .enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
    .build();

User strictUser = strictMapper.readValue(json, User.class);

This now throws an UnrecognizedPropertyException.

6.2. Fast Floating-Point Operations

Jackson 3 enables fast floating-point parsing and writing algorithms by default, significantly increasing performance when processing heavy numerical payloads.

In the late Jackson 2.x releases, we had to manually activate this behavior by configuring the factory features StreamReadFeature.USE_FAST_DOUBLE_PARSER:

JsonFactory.builder()
    .enable(StreamReadFeature.USE_FAST_DOUBLE_PARSER)
    .build()

In Jackson 3, we benefit from this performance boost right out of the box.

6.3. Simplified Date and Time Formatting

Jackson 3 introduces DateTimeFeature, consolidating date and time configuration options across standard JDK dates, Java 8 java.time, and Joda-Time into a single, unified feature set:

JsonMapper mapper = JsonMapper.builder()
    .enable(DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS)
    .build();

We can now format dates globally across all date types.

6.4. Standard Bean Naming

Jackson 3 bakes standard bean naming into its core engine as the permanent default behavior. Because this behavior is no longer optional, Jackson 3 removed the MapperFeature.USE_STD_BEAN_NAMING configuration flag entirely.

Now, we get more consistent property naming out of the box, as we can derive property names from standard getters and setters. Consider a Java class with a getter getTheURL():

class Link {
    private String address;

    public Link(String address) {
        this.address = address;
    }

    public String getTheURL() {
        return address;
    }
}
// ...
String json = mapper.writeValueAsString(new Link("https://baeldung.com"));

Note that Jackson derives JSON property names from getters instead of private fields. In this example, the getter getTheURL() determines the output key theURL:

{"theURL":"https://baeldung.com"}

The backing private field address isn’t considered.

7. Enhancements to the JsonNode Tree Model

The JsonNode tree model remains crucial for working with unstructured data. In Jackson 3, the API underwent several structural updates to make traversing JSON trees safer and more intuitive.

First, the node trees now expose dedicated subtypes, such as ObjectTreeNode and ArrayTreeNode. This shift provides better type-safety and clearer intentions when manipulating complex JSON structures, compared to checking node types on a generic JsonNode interface.

The API also introduces safer method names to align with Java conventions. For example, JsonParser.getText() has been renamed to getString() to avoid ambiguity and standardize the naming scheme.

Finally, Jackson 3 introduces optional value accessors, such as intValueOpt(), asInt(), and required(). They eliminate the need for manual null checking and provide a much cleaner approach to extracting data.

Here’s an example showing all the three updates:

String json = "{\"product\":\"Laptop\",\"price\":1200}";
JsonNode root = mapper.readTree(json);

String product = root.get("product").asString();
OptionalInt price = root.get("price").intValueOpt();

In this snippet, we parse a raw JSON string into a tree model. We then safely navigate the structure using the get() method and extract typed values using the new asString() and intValueOpt() accessors. This approach bypasses the clunky type-checking and manual casting that were often required in previous versions.

8. Conclusion

In this article, we explored the major architectural and functional changes introduced in Jackson 3.0. By raising the baseline to Java 17, the library drops years of technical debt and natively embraces modern Java features like Records, java.util.Optional, and the java.time API without the need for external modules.

The shift toward strict immutability via the builder pattern successfully resolves historic thread-safety issues, while the transition to unchecked exceptions greatly improves developer readability, especially when working with modern Java Streams. Additionally, smarter configuration defaults and Tree Model enhancements make everyday JSON processing cleaner and more intuitive.

While migrating from the 2.x line requires some work, the long-term benefits of a faster, safer, and more robust API make the upgrade well worth the effort.

As always, the complete source code for all the examples is available over on GitHub.

Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (tag=Refactoring)
announcement - icon

Modern Java teams move fast — but codebases don’t always keep up. Frameworks change, dependencies drift, and tech debt builds until it starts to drag on delivery. OpenRewrite was built to fix that: an open-source refactoring engine that automates repetitive code changes while keeping developer intent intact.

The monthly training series, led by the creators and maintainers of OpenRewrite at Moderne, walks through real-world migrations and modernization patterns. Whether you’re new to recipes or ready to write your own, you’ll learn practical ways to refactor safely and at scale.

If you’ve ever wished refactoring felt as natural — and as fast — as writing code, this is a good place to start.

eBook Jackson – NPI EA – 3 (cat = Jackson)
eBook Jackson – NPI (cat = Jackson)
guest
0 Comments
Oldest
Newest