Skip to content

Jackson Release 2.16

Tatu Saloranta edited this page Mar 13, 2024 · 125 revisions

Jackson Version 2.16 was released on November 15, 2023. One release candidate (2.16.0-rc1) was released prior to final 2.16.0.

This wiki page gives a list of links to all changes (with brief descriptions) that are included, as well as about original plans for bigger changes (and in some cases changes to plans, postponing).

Status

Branch is open and patches will be released.

Patches

Documentation

Articles, Blog posts

New Modules

Android Record module

jackson-module-android-record offers support for Record type on Android platform, where Java records are supported through "de-sugaring".

"Jakarta" variant of Guice module

Guice 7 module is a "Jakarta" variant with jakarta.inject instead of javax.inject): needed to work with Guice 7.

Most Wanted features implemented


Changes, compatibility

Compatibility: platform requirements

JDK

Same as Jackson 2.15

Kotlin

kotlin-core versions supported changed, as follows (see module-kotlin#684 for details)

  • Jackson 2.15.x: Kotlin-core 1.5 - 1.8
  • Jackson 2.16.x: Kotlin-core 1.6 - 1.9

that is, support for 1.5 was dropped and support for 1.9 now verified.

jackson-module-kotlin removes MissingKotlinParameterException and replaces it with MismatchedInputException, which was its parent class(KOTLIN#617).

Scala

Jackson 2.16 has full support for Scala 2.11, 2.12, 2.13 and 3.3+. Java 8 is the minimum supported Java version.

Compatibility, dependencies

Changes, behavior

Streaming (jackson-core)

  • Default setting for StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION (aka JsonParser.Feature.INCLUDE_SOURCE_IN_LOCATION) changed to false for improved defaults wrt security (less information leakage by default).
  • Behavior of Version (accessible by JsonFactory.version() and similar accessors in JsonParser, JsonGenerator etc) comparison (Version.compareTo()) changed to consider Snapshot version, if any,

Databind

  • java.util.Locale coercion from empty String will now result in Locale.ROOT (and not null) even if DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT is enabled (see databind#4009)

Processing Limits (for jackson-core, format modules)

General

2.16 adds maximum processing limits for certain aspects of content generation (writing, serialization) as described below. Addition of the general feature (and one of limits) was included under jackson-core#1048.

Implemented limits are:

  • Expressed in input units -- bytes or chars -- depending on input source
  • Defined as longest allowed length, but not necessarily imposed at 100% accuracy: that is, if maximum allowed length is specified as 1000 units, something with length of, say 1003 may not cause exception (but 1500 would)
  • Defined in new StreamWriteConstraints class, configurable on per-JsonFactory basis

Maximum Document length

Implementation of jackson-core#1046 sets upper limit of longest accepted input for parsing. Default limits is:

  • Unlimited (marked as -1) -- no maximum length specified for input

Maximum Output nesting depth

Implementation of jackson-core#1055 sets upper limit on maximum output nesting (Objects, Arrays) when generating output (writing JSON etc). Default limit is:

  • 1000 levels

Maximum Property name length

Implementation of jackson-core#1047 sets maximum length of allowed Property names when parsing input. Default limit is:

  • 50,000 units (bytes or chars, depending on input source)

Major focus areas, planned vs implemented

Improved/Extended Processing Limits

Implemented, See Above.

Canonical JSON Output

Partial work, including:

  • #1042: Allow configuring spaces before and/or after the colon in DefaultPrettyPrinter
  • #3965: Add JsonNodeFeature.WRITE_PROPERTIES_SORTED for sorting ObjectNode properties on serialization

Rewrite of Property Introspection (internal)

Was Not Started Yet (same old story...) during 2.16 development.


Full Change list

Changes, core

  • #223: Add new OptBoolean valued property in @JsonTypeInfo to allow per-type configuration of strict type id handling
  • #229: Add JsonTypeInfo.Value object (backport from 3.0)
  • #234: Add new JsonTypeInfo.Id.SIMPLE_NAME
  • #991: Change StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION default to false in Jackson 2.16
  • #1007: Improve error message for StreamReadConstraints violations
  • #1015: JsonFactory implementations should respect CANONICALIZE_FIELD_NAMES
  • #1035: Root cause for failing test for testMangledIntsBytes() in ParserErrorHandlingTest
  • #1036: Allow all array elements in JsonPointerBasedFilter
  • #1039: Indicate explicitly blocked sources as "REDACTED" instead of "UNKNOWN" in JsonLocation
  • #1041: Start using AssertJ in unit tests
  • #1042: Allow configuring spaces before and/or after the colon in DefaultPrettyPrinter (for Canonical JSON)
  • #1046: Add configurable limit for the maximum number of bytes/chars of content to parse before failing
  • #1047: Add configurable limit for the maximum length of Object property names to parse before failing
  • #1048: Add configurable processing limits for JSON generator (StreamWriteConstraints)
  • #1050: Compare _snapshotInfo in Version
  • #1051: Add JsonGeneratorDecorator to allow decorating JsonGenerators
  • #1064: Add full set of BufferRecyclerPool implementations
  • #1066: Add configurable error report behavior via ErrorReportConfiguration
  • #1081: Make ByteSourceJsonBootstrapper use StringReader for < 8KiB byte[] inputs
  • #1089: Allow pluggable buffer recycling via new RecyclerPool extension point
  • #1136: Change parsing error message to mention -INF
  • #1770: Incorrect deserialization for BigDecimal numbers
  • #2502: Add a way to configure caches Jackson uses
  • #2787: Mix-ins do not work for Enums
  • #3133: Map deserialization results in different numeric classes based on json ordering (BigDecimal / Double) when used in combination with @JsonSubTypes
  • #3251: Generic class with generic field of runtime type Double is deserialized as BigDecimal when used with @JsonTypeInfo and JsonTypeInfo.As.EXISTING_PROPERTY
  • #3277: Combination of @JsonUnwrapped and @JsonAnySetter results in BigDecimal instead of Double
  • #3647: @JsonIgnoreProperties not working with @JsonValue
  • #3780: Deprecated JsonNode.with(String) suggests using JsonNode.withObject(String) but it is not the same thing
  • #3838: Difference in the handling of ObjectId-property in JsonIdentityInfo depending on the deserialization route
  • #3877: Add new OptBoolean valued property in @JsonTypeInfo, handling, to allow per-polymorphic type loose Type Id handling
  • #3906: Regression: 2.15.0 breaks deserialization for records when mapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE)
  • #3924: Incorrect target type when disabling coercion, trying to deserialize String from Array/Object
  • #3928: @JsonProperty on constructor parameter changes default field serialization order
  • #3950: Create new JavaType subtype IterationType (extending SimpleType)
  • #3953: Use JsonTypeInfo.Value for annotation handling
  • #3965: Add JsonNodeFeature.WRITE_PROPERTIES_SORTED for sorting ObjectNode properties on serialization (for Canonical JSON)
  • #4008: Optimize ObjectNode findValue(s) and findParent(s) fast paths
  • #4009: Locale "" is deserialised as null if ACCEPT_EMPTY_STRING_AS_NULL_OBJECT is enabled
  • #4011: Add guardrail setting for TypeParser handling of type parameters
  • #4036: Use @JsonProperty for Enum values also when READ_ENUMS_USING_TO_STRING enabled
  • #4037: Fix Enum deserialization to use @JsonProperty, @JsonAlias even if EnumNamingStrategy used
  • #4039: Use @JsonProperty and lowercase feature when serializing Enums despite using toString()
  • #4040: Use @JsonProperty over EnumNamingStrategy for Enum serialization
  • #4041: Actually cache EnumValues#internalMap
  • #4047: ObjectMapper.valueToTree() will ignore the configuration SerializationFeature.WRAP_ROOT_VALUE
  • #4056: Provide the "ObjectMapper.treeToValue(TreeNode, TypeReference)" method
  • #4060: Expose NativeImageUtil.isRunningInNativeImage() method
  • #4061: Add JsonTypeInfo.Id.SIMPLE_NAME which defaults type id to Class.getSimpleName()
  • #4071: Impossible to deserialize custom Throwable sub-classes that do not have single-String constructors
  • #4078: java.desktop module is no longer optional
  • #4082: ClassUtil fails with java.lang.reflect.InaccessibleObjectException trying to setAccessible on OptionalInt with JDK 17+
  • #4090: Support sequenced collections (JDK 21)
  • #4095: Add withObjectProperty(String), withArrayProperty(String) in JsonNode
  • #4096: Change JsonNode.withObject(String) to work similar to withArray() wrt argument
  • #4144: Log WARN if deprecated subclasses of PropertyNamingStrategy is used
  • #4145: NPE when transforming a tree to a model class object, at ArrayNode.elements()
  • #4153: Deprecated ObjectReader.withType(Type) has no direct replacement; need forType(Type)
  • #4159: Add new DefaultTyping.NON_FINAL_AND_ENUMS to allow Default Typing for Enums
  • #4164: Do not rewind position when serializing direct ByteBuffer
  • #4175: Exception when deserialization of private record with default constructor
  • #4184: BeanDeserializer updates currentValue incorrectly when deserialising empty Object

Changes, data formats

  • #198: Support writing numbers as quoted Strings with CsvGenerator.Feature.ALWAYS_QUOTE_NUMBERS
  • #422: Add removeColumn() method in CsvSchema.Builder
  • #438: BigInteger and BigDecimal are quoted if CsvGenerator.Feature.ALWAYS_QUOTE_STRINGS enabled
  • #403: Remove Smile-specific buffer-recycling
  • #148: @JacksonXmlElementWrapper not respected when serializing Iterators / Iterables
  • #302: Unable to serialize top-level Java8 Stream
  • #329: @JacksonXmlElementWrapper ignored on Stream
  • #599: Use IterationType in TypeUtil

YAML

  • #400: IllegalArgumentException when attempting to decode invalid UTF-8 surrogate by SnakeYAML
  • #406: NumberFormatException from SnakeYAML due to int overflow for corrupt YAML version
  • #435: Minor parsing validation miss: tagged as int, exception on underscore-only values
  • #437: Update SnakeYAML dependency to 2.2

Changes, datatypes

  • #263: Add JavaTimeFeature.ALWAYS_ALLOW_STRINGIFIED_TIMESTAMPS to allow parsing quoted numbers when using a custom DateTimeFormatter
  • #272: JsonFormat.Feature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS not respected when deserialising Instants
  • #281: Add JavaTimeFeature.NORMALIZE_DESERIALIZED_ZONE_ID to allow disabling ZoneId normalization on deserialization

Guava

  • #90: Cache Serialization serializes empty contents
  • #113: Update default Guava dependency for Jackson 2.16 from Guava 23.x to 25.x
  • #116: Suppport simple deserialization of Cache
  • #117: ImmutableRangeSet fails to deserialize without explicit deserializer
  • #140: HibernateModule.REPLACE_PERSISTENT_COLLECTIONS not working when FetchType.EAGER
  • #37: Fix class path scanning on each deserialization
  • #117: PCollections module info (module-info.class) incorrect

Changes, Other modules

Afterburner

  • #216: Disable when running in native-image
  • #223: IncompatibleClassChangeError when deserializing a class implementing an interface with default get/set implementations

Blackbird

  • #181: BlackBird proxy object error in Java 17
  • #216: Disable when running in native-image

Guice

  • #209: Add guice7 (jakarta.inject) module

Jakarta XML Bind Annotations

  • #219: Using jackson-module-jakarta-xmlbind-annotations 2.15.2 fails in OSGi Environment with JAXB 4

Changes, JVM Languages

  • #682: Remove MissingKotlinParameterException and replace with MismatchedInputException
  • #684: Kotlin 1.5 has been deprecated and the minimum supported Kotlin version will be updated to 1.6
  • #685: Streamline default value management for KotlinFeatures. This improves the initialization cost of kotlin-module a little.
  • #686: Added KotlinPropertyNameAsImplicitName feature to use Kotlin property names as implicit names for getters. Enabling this feature eliminates some of the problems summarized in #630, but also causes some behavioral changes and performance degradation.
  • #687: Optimize and Refactor KotlinValueInstantiator.createFromObjectWith. This improves deserialization throughput about 1.3 ~ 1.5 times faster.
  • #689: Added UseJavaDurationConversion feature. By enabling this feature and adding the Java Time module, Kotlin Duration can be handled in the same way as Java Duration.
  • #700: Reduce the load on the search process for serializers.
  • #707: If JsonSetter(nulls = Nulls.SKIP) is specified, the default argument is now used when null.
  • #635: upgrade to Scala 3.3 (LTS release)
  • #532: Issue reading @JsonValue annotations. This is fixed by using Scala 3.3. Users who need this issue fixed should be able to just upgrade their Scala version without waiting on a jackson-module-scala 2.16.0 release
  • #644: Registering Jackson Module Scala in an ObjectMapper can affect the property name resolution of non-Scala classes which can affect the behavior when you serialize/deserialize those classes.
  • #647: Make ScalaObjectDeserializerModule part of DefaultScalaModule

Changes, Providers

No changes to JAX-RS or Jakarta-RS providers.

Clone this wiki locally