Skip to content

Jackson Release 2.23

Tatu Saloranta edited this page Nov 11, 2026 · 78 revisions

Jackson Version 2.23(.0) was released on November 7, 2026. It contains all fixes up to LTS release 2.21.9 (in addition to what is listed here)

This wiki page gives a list of links to all changes (with brief descriptions) that are included.

Status

Branch is open for new patch releases.

It is not designated as Long-Term-Support (LTS) since 2.21 is a LTS.

Patches

Documentation

Articles, Blog posts

Changes, compatibility

Android

Same as Jackson 2.22, SDK 26

JDK

Same as Jackson 2.22; mostly Java 8, with some modules requiring later JDKs:

  • jackson-datatype-hibernate: JDK 17 for some modules (Hibernate 7)
  • jackson-jakarta-providers: JDK 11

Kotlin

Same as Jackson 2.22

Compatibility: datatype modules

No changes.

Changes, behavior

None.


Major focus area(s)

Maintenance (bug fixes).


Full Change list

Changes, core

No changes

  • #1622: UTF8JsonGenerator.writeBinary() should allocate buffer based on supplied length
  • #1683: JSON\uXXXX escape accepts lone surrogates in field names for ReaderBasedJsonParser
  • #1748: Unquoted non-ASCII property names fail in UTF-8 byte parsers with ALLOW_UNQUOTED_FIELD_NAMES
  • #1782: Overlong 2- and 3-byte UTF-8 sequences in String values and comments are decoded instead of rejected
  • #1784: UTF-8 parsers may return wrong cached property name for names containing 0xFF bytes
  • #1787: CharTypes#charToHex handles non-ASCII incorrectly
  • #1792: Validate maxStringLength for string values in getString(Writer)
  • #1794: maxStringLength not enforced by getBinaryValue() when decoding Base64 directly from input
  • #1795: UTF8DataInputJsonParser accepts any control character as white space between tokens
  • #1800: Don't read past end of byte[] slice for UTF-16 input in ByteSourceJsonBootstrapper
  • #1813: getDoubleValue() returns 0.0 after getNumberType(), getFloatValue() for floating-point value
  • #1814: getBigIntegerValue() fails after getNumberType(), getDoubleValue()/getFloatValue() for BigInteger
  • #1815: Stale BigDecimal from previous token returned by getBigIntegerValue() after getNumberType()
  • #6077: FAIL_ON_UNEXPECTED_VIEW_PROPERTIES not being respected with constructor-backed properties
  • #6210: @JsonAlias ignored in enum if @JsonValue is present
  • #6240: @JsonValue ignored on getter also annotated with @JsonKey
  • #6261: Support @JsonView on properties-based Creator parameters of Enum, Map and EnumMap types
  • #6295: @JsonInclude(NON_DEFAULT) omits a changed array property when the default array contains null
  • #6296: Duplicate properties merged under the wrong key in non-vanilla UntypedObjectDeserializer
  • #6300: NPE when a DeserializationProblemHandler returns null for byte[] (single value unwrapped) and char[] elements
  • #6305: InetSocketAddress deserialization ignores text after the closing bracket of an IPv6 address
  • #6306: NPE serializing @JsonIdentityReference(alwaysAsId = true) to an object whose id is null
  • #6315: Map key deserializers should apply same type checks as bean deserializers
  • #6329: Add JDK-bundled RowSet gadget siblings to deserialization deny-list
  • #6338: readerForUpdating() ignores @JsonSetter(nulls = Nulls.SKIP) for creator properties: existing value is overwritten with null
  • #6339: Enum aliases from an appended AnnotationIntrospector are discarded: JacksonAnnotationIntrospector.findEnumAliases() overwrites every slot
  • #6399: NullSerializer should not be annotated with @JacksonStdImpl

Changes, dataformats

Avro

  • #745: Fix Avro bugs
  • #797: Apache decoder fails with UnsupportedOperationException when AvroParser.Feature.AVRO_BUFFERING disabled
  • #845: Avro parsers' getText(Writer) write wrong text for numeric tokens, NPE for binary; ApacheAvroParserImpl.getText() returns stale text for non-String scalars
  • #855: arrayNext() / mapNext() on Decoder passed to @AvroEncode CustomEncoding lose elements and the following field
  • #862: Invalid UTF-8 sequences (overlong, surrogates, > U+10FFFF, bad continuation bytes) not rejected in Avro string values
  • #896: Reject negative byte size of skipped Avro Array/Map block
  • #901: Read string values and Map keys in chunks in Apache Avro decoder

CBOR

  • #842: CBORGenerator writes wrong exponent for BigDecimal with scale Integer.MIN_VALUE
  • #844: CBORParser.getText(Writer) writes stale text for numeric tokens, NPE for binary
  • #860: Invalid UTF-8 sequences (overlong, surrogates, > U+10FFFF) not rejected in CBOR names, text values
  • #870: Reject 0xFF lead byte in last quad of property names
  • #888: nextFieldName(SerializableString) matches against JSON-escaped name bytes (asQuotedUTF8())

CSV

  • #699: Add ability to modify columns in CsvSchema.Builder by name
  • #763: Overlong UTF-8 sequences not rejected in CSV

Ion

  • #800: Upgrade ion-java dependency to 1.12.1

Protobuf

  • #846: ProtobufParser.getText(Writer) writes stale text for numeric tokens, NPE for binary
  • #863: Invalid UTF-8 sequences (overlong, surrogates, > U+10FFFF, bad continuation bytes) not rejected in Protobuf string values
  • #881: Known field after a skipped unknown field gets wrong wire type / state / location, differently per nextToken() / nextName*()

Smile

  • #831: Non-blocking Smile parser reports wrong currentLocation() / currentTokenLocation() byte offsets
  • #834: SmileGenerator silently writes wrong BigDecimal scale outside [-2^30, 2^30-1]
  • #835: SmileParser.getText(Writer) writes stale text for numeric tokens
  • #838: Non-blocking Smile parser requires a header after a root-level scalar value (rejects end marker, following root values)
  • #861: Invalid UTF-8 sequences (overlong, surrogates, > U+10FFFF, bad continuation bytes) not rejected in Smile string values
  • #869: Reject 0xFF lead byte in last quad of property names
  • #888: nextFieldName(SerializableString) matches against JSON-escaped name bytes (asQuotedUTF8())
  • #895: Enforce maxNestingDepth in non-blocking Smile parser

TOML

  • #663: TOML parser: int64 max value parsed as truncated long
  • #696: TomlMapper writes NaN/Infinity as bare tokens, producing TOML it cannot read back
  • #746: Fix remaining TomlGenerator String write issues
  • #894: Read stream to end for negative length in writeBinary(InputStream)
  • #899: Return null from nextStringValue() at end of input

YAML

  • #764: Overlong UTF-8 sequences not rejected in YAML

Changes, data types

  • #190: Reject out-of-range int in PeriodDeserializer object form
  • #191: Reject malformed zone id suffix in DateTimeDeserializer
  • #192: Resolve LocalTime timestamps with the configured time zone
  • #193: Reject partial LocalDateTime array instead of returning null
  • #194: Fix timestamp time zone resolution (explicit zone equal to JVM default; ADJUST_DATES_TO_CONTEXT_TIME_ZONE)
  • #195: Invalid String values for LocalDate/LocalDateTime/LocalTime/DateTime fail with raw Joda IllegalArgumentException
  • #197: DateTimeZoneDeserializer leaks raw NumberFormatException for out-of-int-range timestamp String
  • #199: Reject timestamp that overflows zone offset in Local* deserializers
  • #200: Reject overflowing period in IntervalDeserializer instead of leaking ArithmeticException

Changes, Other modules

Blackbird

  • #363: Blackbird ignores @JsonSetter(nulls = Nulls.SKIP) for properties of beans with a properties-based creator
  • #364: Blackbird: use generated setters for builder-based deserialization
  • #366: Blackbird: skip generated setters the accessor can't call
  • #367: Blackbird: avoid retrying failed bean setters
  • #375: Blackbird: use generated accessors for primitive double properties
  • #377: Don't generate getters for inaccessible getters made accessible

Java 8 Date/time

  • #76: Missing milliseconds when serializing Java 8 date-time if they are zeros (add JavaTimeFeature.ALWAYS_WRITE_SUBSECOND_DIGITS)

Changes, other

  • #223: Reading List<List<X>> or List<String[]> never returns when an element isn't an array

Clone this wiki locally