Lombok
Jackson
Compatibility Issues
Java
Software Development

Lombok 1.18.0 and Jackson 2.9.6 not working together

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

When Lombok 1.18.0 and Jackson 2.9.6 appear to "stop working together," the failure is usually not that the libraries are incompatible at a binary level. The real problem is that Jackson can no longer infer how to construct a class once Lombok-generated constructors and metadata stop matching what Jackson expects during deserialization.

Why Deserialization Starts Failing

Jackson needs a clear way to create an object from JSON. It can do that through:

  • A no-args constructor plus setters
  • An explicitly annotated constructor
  • A builder configuration Jackson understands
  • Constructor parameter names that are preserved and discoverable

Lombok changes what code is generated at compile time. Around Lombok 1.18.0, many teams ran into issues because Jackson could no longer infer constructor parameter names from the generated code path they were relying on before.

A typical failure looks like this:

java
1import lombok.Value;
2
3@Value
4public class UserDto {
5    String firstName;
6    String lastName;
7}

Serializing this class works fine. Deserializing it often fails, because Jackson sees an all-args constructor but does not know which JSON fields map to which constructor arguments unless extra metadata is available.

The Most Reliable Fix

The safest fix is to make object creation explicit with @JsonCreator and @JsonProperty.

java
1import com.fasterxml.jackson.annotation.JsonCreator;
2import com.fasterxml.jackson.annotation.JsonProperty;
3import lombok.Value;
4
5@Value
6public class UserDto {
7    String firstName;
8    String lastName;
9
10    @JsonCreator
11    public UserDto(
12        @JsonProperty("firstName") String firstName,
13        @JsonProperty("lastName") String lastName
14    ) {
15        this.firstName = firstName;
16        this.lastName = lastName;
17    }
18}

With this version, Jackson no longer needs to guess. The JSON contract is written directly into the constructor signature.

Other Fixes That Often Work

If you want to keep Lombok-generated constructors, you still need to give Jackson enough metadata.

One option is compiling with Java parameter metadata:

xml
1<plugin>
2  <artifactId>maven-compiler-plugin</artifactId>
3  <configuration>
4    <compilerArgs>
5      <arg>-parameters</arg>
6    </compilerArgs>
7  </configuration>
8</plugin>

Another option is asking Lombok to add constructor-property metadata again:

properties
lombok.anyConstructor.addConstructorProperties = true

Place that in lombok.config so the generated constructor exposes names in a form Jackson can consume more reliably.

For mutable DTOs, a simpler workaround is using a no-args constructor and setters:

java
1import lombok.Data;
2import lombok.NoArgsConstructor;
3
4@Data
5@NoArgsConstructor
6public class UserDto {
7    private String firstName;
8    private String lastName;
9}

That is less elegant for immutable models, but it removes the constructor-parameter discovery problem entirely.

Builder Cases Need Extra Care

Another common trap is combining Lombok builders with Jackson and assuming Jackson will automatically use them for deserialization. It usually will not. If your model uses @Builder, you need builder-specific Jackson configuration or an explicit creator method.

A modern codebase may use Lombok's later @Jacksonized support, but that feature is outside the original 1.18.0 and 2.9.6 pairing. For the version combination in this article, explicit annotations are the safer approach.

How to Debug the Exact Failure

Check the exception text carefully. Messages like these point to creator configuration issues:

  • "Cannot construct instance"
  • "No suitable constructor found"
  • "Cannot deserialize from Object value"

If serialization works but deserialization fails, focus on object construction, not on field visibility or JSON naming first.

Common Pitfalls

  • Assuming @Value or @Data automatically makes a class deserializable by Jackson.
  • Relying on generated constructors without preserving parameter metadata.
  • Mixing immutable design with a no-args constructor fix and then wondering why invariants become weak.
  • Using @Builder without telling Jackson how that builder should be consumed.

Summary

  • The issue is usually missing constructor metadata, not a total Lombok and Jackson incompatibility.
  • The most reliable fix is an explicit @JsonCreator constructor with @JsonProperty annotations.
  • '-parameters and lombok.config can help Jackson infer constructor arguments.'
  • Mutable DTOs can fall back to a no-args constructor plus setters.
  • If deserialization fails, investigate how Jackson is supposed to instantiate the class.

Course illustration
Course illustration

All Rights Reserved.