Skip to content

Breaking change in 2.12: Generated Gson adapters incompatible with JsonSerializer registration for Optional fields #1631

@shubhamdarekar

Description

@shubhamdarekar

Description:

Immutables 2.12 introduced a breaking change in how generated Gson adapters handle Optional fields when the inner type T is registered as JsonSerializer/JsonDeserializer.

Breaking Change Details:

Working in 2.11.1 and earlier: Generated adapters worked with both TypeAdapter and JsonSerializer/JsonDeserializer registration patterns
Broken in 2.12: Generated adapters now fail when inner type is registered as JsonSerializer/JsonDeserializer
Problem: The generated code uses OptionalTypeAdapter.FACTORY which strictly requires a TypeAdapter delegate. When T is registered as JsonSerializer, Gson wraps it in TreeTypeAdapter, causing serialization failures.

Minimal Reproduction:

@Value.Immutable
public interface Example {
   Optional<Instant> timestamp();
}

// This breaks in 2.12 (worked in 2.11.1):
gson.registerTypeAdapter(Instant.class, new InstantSerializer());

// This still works:
gson.registerTypeAdapter(Instant.class, new InstantTypeAdapter());

Impact:

Forced migration from 2.11.1 to 2.12 breaks existing codebases
Requires manual workarounds (wrapping JsonSerializer in TypeAdapter)
No migration path documented in release notes
Expected Behavior: Generated adapters should maintain backward compatibility with JsonSerializer registration patterns, or provide clear migration guidance.

Environment:

Immutables: 2.12.x (regression from 2.11.1)
Gson: 2.8.x - 2.10.x
Affected types: Any Optional where T uses JsonSerializer

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions