Jackson 2.11 features

(annotations for jackson-jr, BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES)

@cowtowncoder
5 min readApr 28, 2020

Jackson 2.11.0 was just released on April 26, 2020. This time releasing a new minor version was more along “classic” Jackson timeline — it took 7 months which is longer than with 1.x, but much shorter than 2.10 which took 2 years to complete.

As usual, there are full 2.11 release notes that include all changes included — almost 50 all in all, mostly bug fixes — and this blog post gives an overview of only more significant added or extended features.

Compared to 2.10 there are no major API evolution steps towards 3.x compatibility: focus is on filling the gaps and solidifying existing API, coverage.

New Module: jackson-jr-annotation-support

One of the biggest things I had to leave out of 2.10 was [jackson-jr#32]: “Add support for a subset of jackson annotations”. While Jackson-jr is explicitly designed to be “lean and mean” system, with limited configurability, it seemed (based on some dogfooding) that a little bit of configurability for most common use cases — property discovery defaults, renaming, ignoring — would go a long way in making it much more usable for real-world usage.

What this means that there is now a new optional Extension (implementation of JacksonJrExtension) for jackson-jr called JacksonAnnotationExtension. It is part of Jackson-jr repository, and can be added with Maven dependency:

<dependency>
<groupId>com.fasterxml.jackson.jr</groupId>
<artifactId>jackson-jr-annotation-support</artifactId>
<version>2.11.0</version>
</dependency>

and enabled by constructing a JSON instance (use of builder-style construction was also added in 2.11) like so:

JSON j = JSON.builder().register(JacksonAnnotationExtension.std)
// add other configuration, if any
.build();

after which some standard Jackson annotations are supported when reading/writing JSON using JSON instance. Supported annotations include:

  • @JsonProperty for basic inclusion, renaming
  • @JsonPropertyOrder for defining specific order of properties when writing
  • @JsonIgnore / @JsonIgnoreProperties for ignoring specified visible properties
  • @JsonAlias for specifying alternate names to accept when reading
  • @JsonAutoDetect for changing default visibility rules for methods (can ignore public getters/setters and force use of annotations) and fields (can make non-public fields visible)

So essentially support focuses on basic renaming, reordering and inclusion/removal of properties. You could, for example, have POJO like:

public class NameSimple {
@JsonProperty("firstName")
protected String _first;
@JsonProperty // no rename but make visible
protected String lastName;
public String getFirstName() { return _first; }
public String getLastName() { return lastName; }
}

and then read value with:

NameSimple name = j.beanFrom("{\"firstName\":\"Bob\", \"lastName\":\"Burger\"}", NameSimple.class);

Usage should be straight-forward, and cover most commonly needed “simple” annotation usage. Support for more Jackson annotations may be added over time based on user feedback.

Feedback on this feature would be warmly appreciated!

New Module: joda-datatype-money

While Joda date-time library is by far the most popular of the libraries, Joda.org actually has a few other libraries, including “Joda-Money”.
Basic support for 2 main types — Money, CurrencyUnit — was added via jackson-datatype-joda-money datatype library, added to new jackson-datatypes-misc repository (2 existing datatype libraries, jackson-datatype-jsr353, jackson-datatype-json-org, were also moved to this new repository to simplify Jackson release process).

Use is as with other datatype libraries:

ObjectMapper mapper = new JsonMapper.builder() // with 2.10
.addModule(JodaMoneyModule())
.build();
// or, pre-2.10
mapper = new ObjectMapper()
.registerModule(new JodaMoneyModule());

and you can now have POJOs with above-mentioned 2 Joda-money types.

Even more secure defaults: BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES

Jackson 2.10 added “Safe Default Typing” (use of allow-based vs block-list-based checks), which allows solving the problem of potentially unsafe polymorphic deserialization (see “On Jackson CVEs” if you are not familiar with the issue).

But although this solution works as long as users adopt new safe methods, and avoid use of now-deprecated legacy methods that can allow potentially unsafe usage, it seemed there should be ways to further lock down possibly unsafe usage. To do this, 2.11 adds MapperFeature.BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES which will change handling of deprecated enableDefaultTyping() methods (as well as@JsonTypeInfo annotated types that use class name as type id) to block use of problematic “too loose” base types. So, for example this:

ObjectMapper mapper = JsonMapper.builder()
.enable(MapperFeature.BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES)
.build();
Wrapper w = mapper.readValue("{\"value\":{ }}", Wrapper.class);

would fail for type Wrapper:

public class Wrapper {
@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS)
public Object value;
}

since base type java.lang.Object allows potentially unsafe deserialization as described in “On Jackson CVEs…”.

For more details on things like blocked potentially unsafe base types, see [databind#2587].

Addressing Jackson 1.x dependency by Avro module

One big challenge with Avro format backend is that due to dependency to Apache Avro lib, there has been a transitive dependency to Jackson 1.x. While this is not functionally big issue (1.x and 2.x live in different packages, do not conflict), it is less than ideal. The newest versions (1.9.x) of Apache Avro lib do remove that dependency from API, which is great, but unfortunately we can not quite yet upgrade (see [dataformats-binary#167] for more details) Avro dataformat module to use Apache Avro 1.9.0.

However, what is done in 2.11.0 is that we removed jackson 1.x dependency by jackson-dataformat-avro at least (see [dataformats-binary#195]) so that users may try upgrade on their own — this works for many use cases without problems (but not all).

Our hope is to be able to upgrade to newer Apache Avro library versions in near future.

Misc extended functionality

Besides above-mentioned features, bug fixes, applicability of some existing functionality was extended as well:

  • @JsonAlias for Enums (databind#2352): formerly only applicable for POJO properties, now may be used for Enum types as well
  • @JsonDeserialize.keyUsing / @JsonSerialize.keyUsing as class annotation (databind#2503): in addition to using these on Map-valued POJO properties, can now add directly on Key class itself, to be applied when type used as Map key.
  • @JsonProperty.index used for sorting properties (databind#2555): has lower priority than @JsonPropertyOrder (but higher than alphabetic sorting, if enabled). Very useful for CSV backend, for which it was originally requested
  • Datatype module jackson-datatype-jsr353 (now moved in jackson-datatypes-misc github repo) now also supports deserialization of 2 datatypes added in JSR-374 (json-p 1.1), JsonPatch and @JsonMergePatch.

Plans for 2.12 / 3.0

Immediate plan for Jackson 2.x is to continue with some minor releases, with similar shorter-cycle (ideally 4–6 months between releases), along with concurrent planning for 3.0. Some idea of possible things to address can be found from: https://github.com/FasterXML/jackson-future-ideas/wiki/Jackson-Work-in-Progress which is my personal TODO-list.

Some bigger ideas for improvement in 2.12 are:

  • Improve auto-detection of Constructor creators, including solving/alleviating issues with ambiguous 1-argument constructors (delegating vs properties)
  • Add some sort of “NodeConfig” to configure JsonNode handling separate from POJO handling (since they are logically distinct entity class), part of JSTEP-3 plan (some parts have to wait until 3.0)
  • Focus on fixing issues with dataformat modules, esp. XML: although there was hope to spend time in 2.11 dev cycle with XML module (to close some issues identified during end of 2.10 cycle), not much time was spent there.
  • Possibly beef up Jackson-jr even more: another addition in 2.11, [jackson-jr#70], added ReaderWriterModifier which already gives much more power to developers (and 2.10 already added support for custom ValueReaders and ValueWriters, see “Jackson 2.10 Jackson-jr improvements”)

And as with everything else; feedback welcome (here, and via Twitter accounts “@FasterXML” and “@cowtowncoder”)

--

--

@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