Sitemap

Jackson 2.20.0 released

5 min readAug 29, 2025

Jackson 2.20.0 was released yesterday, after just 4 months since 2.19.0 release (see this blog post about 2.19).
Let’s have a look at what this update delivers (note: as usual, full 2.20 Release Notes list everything included in detail — this is just a quick overview).

2.20 by Stats

Starting by numbers, 2.20.0:

  • Took 4 months from the previous minor release (2.19.0) — fastest minor release in years (2.19 itself was already quick, taking 6 months)
  • Contains about 50 changes (mostly fixes, but some new features as well) — bit less than 80 in 2.19.

So we got another “small minor version”.

Background: preparing for 3.0.0, migration to Sonatype Central

One reason for short(er) development cycle (and fewer changes) is the focus on getting ready for 3.0.0 release. We are up to 3.0.0-rc8 by now, rc9 probably being released in a day or two, hopefully followed by 3.0.0 — goal being to release 3.0.0 in September 2025.
The reason this matters is that there are a few clean up things we want to synchronize between 2.x and 3.0 (complete 2.x deprecations (anything removed from 3.0 must have been deprecated by 2.20); change versioning schema of jackson-annotations (more on this below)). Basically changes that cannot go in a patch release of 2.19.
So to get 3.0.0 out in September 2025, it was important to get 2.20.0 released in August.

Another thing that pushed the new minor version was Sonatype’s EOL’ing of trusty old OSSRH repository, used for publishing to Maven Central.
While publishing changes were backported to 2.18 and 2.19 branches it was good to start the upgrade first in 2.20 branch (and verified with the release candidate).

But let’s check the actual changes: here are the highlights.

Most Wanted: support “iPhone” properties

As explained in [databind#5152], there is a problematic naming pattern for some JSON properties — something reported as an issue countless times over the years: so-called “iPhone” (or “oAuth”) properties.
Basically if a JSON property name:

  1. Starts with upper-case letter(s) — like Phone OR
  2. Starts with a single lower-case letter, followed by an upper-case letter — like iPhone (hence issue name)

there is ambiguity between external name (and possible Java Field name) and matching Bean Getter/Setter names: getter/setter inferred name does not match actual JSON property name.
Specifically following POJO fails to work without additional annotations:

class IPhone {
private String iPhone;

public String getIPhone() {
return iPhone;
}
}

because:

  • Field iPhone — used for deserialization — expects JSON property “iPhone”
  • Getter getIPhone() will produce JSON property “iphone” (or with MapperFeature.USE_STD_BEAN_NAMING “IPhone”) — because translation from getter (or setter) name is fundamentally ambiguous.

So, essentially, Jackson would write JSON like (since getter infers “iphone”):

{ "iphone": "xxx" }

but would expect to receive:

{ "IPhone": "xxx" }

This is particularly problematic with frameworks like Lombok.
Solution before 2.20 has been to use annotations to unify names:

class IPhone {
private String iPhone;

@JsonProperty("iPhone")
public String getIPhone() {
return iPhone;
}
}

But now there is finally a way to handle these cases gracefully without annotations — by enabling new MapperFeature.FIX_FIELD_NAME_UPPER_CASE_PREFIX.
Feature is disabled by default in 2.20 (for backwards-compatibility); it will be enabled by default in 3.0. Enabling the feature will add logic to fix this specific discrepancy without need for annotations.

Important new feature: Binary (Packed) Vectors

One cool technique I wrote about a while ago (see “Super-fast Packed Base64 Vectors”) is an optimization to serialize vectors (usually float[] or double[]) as Base64-encoded Strings instead of simple JSON Arrays. This is much more efficient — surprisingly so — both wrt processing and content size (smaller and faster to encode/decode).

Given working prototype handlers, performance results, it seemed reasonable to add explicit support for this format; it did not happen for 2.19 but got in Jackson 2.20.

To enable support, you can either annotate specific Vector-valued properties:

public class BeanWithBinaryFloatVector {
@JsonFormat(shape = JsonFormat.Shape.BINARY)
public float[] vector;
}

or, configure globally:

ObjectMapper mapper = JsonMapper.builder()
.withConfigOverride(float[].class,
c -> c.setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.BINARY))
).build();

and then this alternate JSON serialization will be used for writing (and accepted on reading).

Version scheme change: drop patch from jackson-annotations (2.20, NOT 2.20.0)

(and make Jackson 3.x use 2.x jackson-annotations!)

One change that has been planned for a long time is the dropping of unused (*) patch version from jackson-annotations: basically versions 2.18.0, 2.18.1 , 2.18.2, 2.18.3 and 2.18.4 are all identical. So we might as well just publish 2.18.
Originally this change was planned only for Jackson 3.0, to maximize versioning compatibility for users that assume all components use the exact same version and do not use jackson-bom.

But when we decided to change the plan so that Jackson 3.0 will continue to use 2.x annotations (**)— version 3.0, specifically depends on 2.20 of jackson-annotations — it was decided that dropping patch version needs to happen with 2.20.0 release.

So: both Jackson 2.20.x and 3.0.x will depend on jackson-annotations 2.20 . Similarly 2.21.x and 3.1.x will (likely) depend on jackson-annotations 2.21 (although theoretically it is possible 3.1.x could depend on 2.20 annotations if 2.21 is not released before 3.1 — we will see).

If above sounds complicated, don’t worry: jackson-databind defines annotation version needed — and more importantly jackson-bom can be used to specify fully compatible version set. So you should rarely need to manually indicate specific jackson-annotations version to use.

(*) Unused during normal times: in theory it is possible some critical problem could require use of patch indicator. This is a very rare occurrence.
(**) Why not go with new 3.0 version of jackson-annotations? JSTEP-1 explains reasoning — in short, this allows using same annotations with both Jackson 2.x and 3.x, making upgrade process bit smoother, avoiding need to duplicate annotations which was sometimes needed for Jackson 1.x -> 2.0 upgrade (and more importantly, eliminates one common source of errors; mismatching annotation package).

New Datatype module: jackson-datatype-hibernate7

Existing datatype support for Hibernate was extended slightly, by contributed Hibernate 7 module (jackson-datatype-hibernate7) registered the usual way:

<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate7</artifactId>
<version>2.20.0</version>
</dependency>
ObjectMapper mapper = JsonMapper.builder()
.addModule(new Hibernate7Module()));
.build();

SBOM Metadata Publishing — almost :-(

As per [JSTEP-14], Jackson artifacts (jars) are now (2.20+) built with SBOM metadata (what are SBOMs? Read here). Intent was to publish this metadata into Maven Central along with artifacts.

But it looks like https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/2.20.0/ does not have expected artifacts. :-(

Rats. It was working at some point… need to go and see what happened.

**EDIT**: looks like publishing worked for 3.0.0-rc4 (https://repo1.maven.org/maven2/tools/jackson/core/jackson-core/3.0.0-rc4/) but no longer for 3.0.0-rc5 (https://repo1.maven.org/maven2/tools/jackson/core/jackson-core/3.0.0-rc5/). Configuration was not changed wrt SBOM plug-in but publishing swiched to Sonatype Central from OSSRH. So something in the newer repository seems to block publishing. Oh well.

Other updated modules

As usual, many extension modules were improved as well. Without more details, here are most notable:

That’s All, Folks!

And now back to working on Yet Another 3.0.0 Release Candidate :)
(I last blogged about 3.0.0-rc4 )

--

--

@cowtowncoder
@cowtowncoder

Written by @cowtowncoder

Open Source developer, most known for Jackson data processor (nee “JSON library”), author of many, many other OSS libraries for Java, from ClassMate to Woodstox

Responses (1)