Repository navigation
Jackson Release 3.3
Jackson Version 3.3 was released on November 7, 2026. It contains all fixes up to LTS release 3.1.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.
Version is under development (under branch 3.x).
It is not designated as Long-Term-Support (LTS) since 3.1 is an LTS.
- 3.3.1 (Not yet released)
TO BE WRITTEN, see https://github.com/FasterXML/jackson-datatypes-collections
SDK 34 for all components (since Jackson 3.2; up from 3.1). Verified by "Animal Sniffer" plug-in.
Same as Jackson 3.2; Java 17, except:
- JDK 25 for [jackson-module-blackbird]
Minimum supported Kotlin has been upgraded to 2.2.
Now requires JDK 25 (unlike JDK in 3.2 and before), after full rewrite via modules-base#359.
None.
TONS of performance improvements, f.ex:
[TO BE WRITTEN]
Issues with at least 5 thumbs-ups that were resolved in this version:
- base-modules#38: Support for fastutil collections
No separate 3.x versions released, uses jackson-annotations 2.23.
-
#1637: Add
JsonPointer.startsWith()method -
#1646: Non-blocking ByteBuffer parser
releaseBuffered()can write already-consumed bytes - #1652: Use faster, no-allocation DoubleToDecimal / FloatToDecimal
- #1654: Stale symbol table child can replace a newer root table
- #1664: UTF-8 byte-backed parsers report raw byte instead of decoded character for invalid root-value separator
- #1674: Encode base64 into exactly-sized char[] instead of StringBuilder
-
#1675: Allocate
ByteArrayBuilderpast-block list lazily -
#1680: Avoid per-character escape-table load in
_writeStringSegmentASCII loop -
#1685: Revisit
BigDecimalParser's 500-character FastDoubleParser threshold (lower to 200) -
#1686: Synchronous decimal number parsing buffers oversized values before
maxNumberLengthvalidation -
#1687: Add
StripedArrayPooland virtual-thread-awareHybridPoolrecycler pools -
#1688: Add
JsonParser.nextNameMatchAndToken(): fused name match plus value-token advance -
#1691: Validate name length in
UTF8DataInputJsonParserbefore quad buffer growth -
#1697: Add
ByteArrayUtilfor codecs to use -
#1704: Add
NumberOutput.outputDouble/outputFloat(char[]), use inWriterBasedJsonGenerator -
#1706: Write number text directly as ASCII bytes in
UTF8JsonGenerator -
#1715: Add
StreamReadConstraints.getMaxBigIntegerScale() - #1727: Fix UTF-8 surrogate validation in String skip path
-
#1731:
FilteringGeneratorDelegate.writeUTF8String()andwriteRawUTF8String()filtered viaincludeRawValue()instead ofincludeString() -
#1738: Add
GuardedOutputStream(non-flushing, non-closingOutputStreamwrapper) for textual format backends -
#1752:
UTF8DataInputJsonParsersould preserve I/O failures during invalid token reporting - #1753: Reject 4-byte UTF-8 sequences exceeding U+10FFFF
- #1760: Extend 4-byte UTF-8 range validation to remaining parser paths
-
#1766:
ReaderBasedJsonParserundercounts number length when fraction or exponent is absent -
#1768:
MergedStreamedge cases: negativeskip(), empty pushback range -
#1771:
ByteArrayBuilder.write(byte[], int, int)does not validateoff/len - #1778: Use local pointer in UTF8StreamJsonParser long-name loop
- #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#charToHexhandles non-ASCII incorrectly -
#1792: Validate maxStringLength for string values in
getString(Writer) -
#1794:
maxStringLengthnot enforced bygetBinaryValue()when decoding Base64 directly from input -
#1795:
UTF8DataInputJsonParseraccepts any control character as white space between tokens -
#1798:
BinaryNameMatcherdoes not pad partial quads: binary parsers match NUL-containing names to known properties -
#1800: Don't read past end of
byte[]slice for UTF-16 input inByteSourceJsonBootstrapper -
#1801: Reject surrogate code points in
UTF32Reader -
#1802: Pad
BufferRecyclerslots to avoid false sharing - #1803: Validate async decimal number lengths before buffer expansion
-
#1813:
getDoubleValue()returns0.0aftergetNumberType(),getFloatValue()for floating-point value -
#1814:
getBigIntegerValue()fails aftergetNumberType(),getDoubleValue()/getFloatValue()forBigInteger -
#1815: Stale
BigDecimalfrom previous token returned bygetBigIntegerValue()aftergetNumberType()
-
#1127:
@JsonTypeInfowithEXTERNAL_PROPERTYdoesn't handle arrays of polymorphic types -
#1803:
TreeTraversingParsershould allow passing of parent context - #3119: Map Key interface not serialized with both type serializer or keyUsing
-
#3182: Support value deduplication for enumeration like values: add
StringCanonicalizingConverter - #3947: Multiple suitable annotated Creator factory methods to be used as the Key deserializer when using record as key in Map
-
#4762:
@JsonValueignores annotations on annotated field (particularly@JsonInclude) -
#5380:
@JsonValueignores propertyInclusion rules for config override -
#6068: 3.x
ObjectMapper.convertValue()stop throwingjava.lang.IllegalArgumentException -
#6091: Current token incorrectly reported when using
@JsonTypeInfo -
#6113: Fix
DOMSerializerto support polymorphic serialization - #6114: Fix QName object deserialization to reject non-String namespaceURI/prefix
-
#6120: Use per-node-type Type Ids for DOM values, reconstruct via DOM factory instead of always parsing a
Document -
#6128: Fail explicitly on POJO that has both
@JsonFormat(shape=ARRAY)and@JsonFilter -
#6130: Allow limiting maximum length of JDK regex
Patternat deser time -
#6136:
@JsonFilterwithserializeAllExcept()does not filter@JsonAnyGetterentries -
#6142:
SerializerCacheread-only lookup is not invalidated when replacing typed serializers -
#6151: Add
DateTimeFeature.ALWAYS_WRITE_SUBSECOND_DIGITS -
#6168: Cache raw parameter types in
AnnotatedConstructor -
#6170: Allow skipping null values for properties handled by
@JsonAnySetter -
#6173: Allow
BeanSerializerModifierto override property serializers -
#6175:
QNameobject form is skipped when polymorphic type id is writtenAs.PROPERTY -
#6178:
JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_VALUESdoes not work forjava.time.Month -
#6187: Make
InvokerHolderaccess inAnnotatedConstructorlazy, to reduce unnecessary eager processing -
#6188:
ThrowableDeserializerdoes not resolve standardThrowableproperty names againstPropertyNamingStrategy -
#6190: Explicit
@JsonViewon a standardThrowableproperty is ignored byThrowableDeserializer -
#6193: Use
JsonParser.nextNameMatchAndToken()in the vanillaBeanDeserializerloops -
#6195: Close managed parser if
readValues()initialization fails -
#6196: Close generator if initialization fails before any content is written in
ObjectMapper,ObjectWriter -
#6197: Fix
ClassCastExceptionforAutoCloseablevalues inObjectMapper.writeValue(JsonGenerator, ...) -
#6198: Make
InvokerHolderaccess inAnnotatedMethodlazy, to reduce unnecessary eager processing -
#6210:
@JsonAliasignored in enum if@JsonValueis present -
#6219: Vanilla
BeanDeserializerfast path never used with default settings in 3.x (due toMapperFeature.DEFAULT_VIEW_INCLUSIONdefault change) -
#6216: Add
TreeTraversingParserconstructors taking explicitStreamReadConstraints -
#6220: Build a property's type deserializer for the type
@JsonDeserialize(as/keyAs/contentAs)refines it to -
#6229:
MapperFeature.DETECT_PARAMETER_NAMES=false silently disables@ConstructorProperties-based Creator detection too -
#6233: Serialize
Monthas Enum name with@JsonFormat(shape = STRING) -
#6239: Explicit
JsonFormat.Shape.NUMBER_INT/NUMBER_FLOATnot honored for nanosecond handling ofjava.timevalues - #6243: Filter ignored Creator properties at build time instead of per-loop read-time checks
-
#6255:
@JsonIgnoreProperties/@JsonIncludePropertiesnot honored forObjectNode/JsonNode@JsonAnyGetterentries -
#6257:
MapDeserializer:@JsonIgnoreProperties/@JsonIncludePropertieschecked after key deserialization, so ignored non-convertible key names still fail -
#6275: Per-type
@JsonInclude(NON_DEFAULT)no longer writes a null over a non-null default, so the null can't round-trip -
#6295:
@JsonInclude(NON_DEFAULT)omits a changed array property when the default array containsnull -
#6296: Duplicate properties merged under the wrong key in non-vanilla
UntypedObjectDeserializer -
#6300: NPE when a
DeserializationProblemHandlerreturnsnullforbyte[](single value unwrapped) andchar[]elements -
#6305:
InetSocketAddressdeserialization ignores text after the closing bracket of an IPv6 address -
#6306: NPE serializing
@JsonIdentityReference(alwaysAsId = true)to an object whose id isnull -
#6309: NPE serializing an Enum whose
toString()returnsnull - #6315: Map key deserializers should apply same type checks as bean deserializers
-
#6317: Global
NON_DEFAULTwithUSE_REAL_INCLUDE_NON_DEFAULTnow writes explicit null` over a non-null default (like per-type); previously nulls were suppressed -
#6319: Global
NON_DEFAULTwithUSE_REAL_INCLUDE_NON_DEFAULTskips "empty" check when default bean cannot be created -
#6320:
LocaleMap keys are still serialized usingLocale.toString()instead ofLocale.toLanguageTag() -
#6324:
ArrayIndexOutOfBoundsExceptionin BeanPropertyMap.withoutProperties()with property-level@JsonIdentityInfo+@JsonIgnorePropertieswhen the value type has@JsonAlias` -
#6325:
NullPointerExceptionwhen a@JsonCreatorreturnsnulland the input has an Object Id forward reference - #6329: Add JDK-bundled RowSet gadget siblings to deserialization deny-list
-
#6332:
@JsonUnwrappeddrops/rejects the type id property of a polymorphic unwrapped value -
#6338:
readerForUpdating()ignores@JsonSetter(nulls = Nulls.SKIP)for creator properties: existing value is overwritten withnull -
#6339: Enum aliases from an appended
AnnotationIntrospectorare discarded:JacksonAnnotationIntrospector.findEnumAliases()overwrites every slot -
#6342:
@JacksonStdImplonBooleanSerializer.AsNumber(3.1.6) makes Blackbird write primitive boolean getters as true/false instead of 1/0 -
#6350:
allowSubTypesWithExplicitDeserializer()deniesjava.sql.Dateandjava.sql.Timestamp:hasExplicitDeserializerFor()returnsfalsefor them -
#6352:
BeanPropertyMap.withProperty()modifies shared map when Object Id property name matches existing property (property-level@JsonIdentityInfo) - #6357: Property-based creator loop (and vanilla loop after unknown property) silently stop on unexpected token within Object, leaving parser mid-Object
-
#6363:
@JsonFormat(shape = ARRAY)Builder loses property values when not using vanilla processing (e.g. with active View):deserializeSetAndReturn()result ignored - #6364: Report property name as found in input (alias) in deserialization error paths
-
#6365:
JsonMapper.builder().filterProvider(...).build()throws NPE when aSimpleFilterProviderhas anullfilter -
#6366:
NullPointerException("Null 'propertyType' passed") deserializing rawMap.Entrywith aShape.POJOconfig override - #6372: Preserve immutable builder updates for unwrapped properties
-
#6374:
@JsonFormat(shape = ARRAY)Builder: structured first extra array element not skipped correctly, leaves parser misaligned -
#6375: Wrap non-Jackson exceptions from
BeanDeserializerBase.handleUnknownProperty() -
#6385: Record update with
readerForUpdating()fails for non-public Record: accessor not made accessible -
#6394:
@JsonFormat(shape = ARRAY)deserialization hangs when input ends beforeEND_ARRAYwhile skipping extra values -
#6398:
@JsonFormat(shape = ARRAY)builder:nullfromDeserializationProblemHandlercauses NPE -
#6399:
NullSerializershould not be annotated with@JacksonStdImpl -
#6401: Raw
IllegalArgumentExceptionescapes polymorphic type-id resolution -
#6410: Object Ids should NOT be affected by JSON Views or
@JsonFilter
- #762: Use varhandle for float/double reads in Avro parser
- #775: Update apache Avro dep to 1.12.2
-
#777: Properties following an
@AvroEncoded value are silently dropped -
#812: Avro: deserializing as
Objectfails withInvalidTypeIdExceptionfor unresolvable type id (3.x regression from 2.x) - #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
stringvalues and Map keys in chunks in Apache Avro decoder
-
#624: Use more efficient (in JDK 17)
Stringconstruction wrt "Compact Strings" -
#752: Use varhandle for array access in
CBORGenerator -
#758: Use SWAR in
CBORParser -
#823:
maxStringLengthnot consistently checked for chunked (indefinite-length) CBOR text values - #860: Invalid UTF-8 sequences (overlong, surrogates, > U+10FFFF) not rejected in CBOR names, text values
-
#876:
nextNameMatch()mixes up unknown property names differing only by NUL bytes (unpadded symbol-table lookup) -
#882:
nextNameMatch()does not pop stringref nesting onEND_OBJECT, resolves later stringrefs against wrong namespace - #870: Reject 0xFF lead byte in last quad of property names
-
#888:
nextFieldName(SerializableString)matches against JSON-escaped name bytes (asQuotedUTF8())
-
#699: Add ability to modify columns in
CsvSchema.Builderby name -
#718: Fix
AUTO_CLOSE_SOURCEoverrides and recycled-buffer leaks on read paths - #719: Fix output lost when writing to OutputStream with auto-close and flush both disabled
-
#721: Write double/float directly into output buffer in
CsvEncoderwhen fast writer enabled - #724: Single-pass String value writing in CsvEncoder; native char[] path; primitive array appends
-
#727: Avoid
char[]copy of value text when parsing integer numbers inCsvDecoder - #763: Overlong UTF-8 sequences not rejected in CSV
-
#780:
IonFactoryleaks stream when parser/generator construction fails forFile/Path
-
#718: Fix
AUTO_CLOSE_SOURCEoverrides and recycled-buffer leaks on read paths - #720: TOML, Java Properties double-close File/Path source on construction failure
-
#722: Use
NumberOutputfor number writes in Properties, TOML and YAML generators -
#734: Fix output lost when writing to
OutputStreamwith auto-close and flush both disabled - #748: Honor stream-write features changed on generator after creation (follow-up to #734, #735)
-
#751: Properties
WriterBackedGenerator: no flush after close, expose caller's stream as output target, don't mask close failures
-
#398: Add
ProtobufReadFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUEfor unknown ids of "non-standard" enums - #763: Use varhandles to to improve perf in Protobuf Parser and Generator
- #863: Invalid UTF-8 sequences (overlong, surrogates, > U+10FFFF, bad continuation bytes) not rejected in Protobuf string values
-
#874:
nextName()/nextNameMatch()do not skip an unread string value, decode its bytes as the next tag -
#879:
nextName()/nextNameMatch()fast paths skip per-token state reset done bynextToken()(stale number, wrong token location) -
#881: Known field after a skipped unknown field gets wrong wire type / state / location, differently per
nextToken()/nextName*()
-
#750: SmileGenerator: avoid String allocation in
SmileGenerator.writeString(char[],int,int) -
#757: Use SWAR in
SmileParser -
#759: Use more efficient
Stringconstruction wrt "Compact Strings" for Smile "long" text values - #767: Optimize async short ASCII string decoding
-
#774: Use SWAR +
VarHandlefor 7-bit binary Smile encode/decode -
#781:
SmileGenerator.writeNumber(String)validates number length against defaultStreamReadConstraintsinstead of configured ones - #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
-
#873:
nextNameMatch()misreads short non-ASCII property names (input not advanced on symbol-table hit, wrong quad count) - #885: Cheap validation of short Smile ASCII property names, to prevent symbol table by-pass
-
#888:
nextFieldName(SerializableString)matches against JSON-escaped name bytes (asQuotedUTF8()) - #889: Speed up UTF-8 validation in Smile: check 3- and 4-byte sequences with a second-byte range lookup keyed on lead byte
-
#895: Enforce
maxNestingDepthin non-blocking Smile parser
- #663: TOML parser: int64 max value parsed as truncated long
- #713: Misc perf fixes (TOML)
-
#718: Fix
AUTO_CLOSE_SOURCEoverrides and recycled-buffer leaks on read paths - #720: TOML, Java Properties double-close File/Path source on construction failure
-
#722: Use
NumberOutputfor number writes in Properties, TOML and YAML generators -
#725: TOML: lookup table for ASCII string categorization; cheaper
writeRaw()variants -
#735: Fix output lost when writing to
OutputStreamwith auto-close and flush both disabled -
#739:
TreeTraversingParsercreated byTomlFactorydoes not use factory'sStreamReadConstraints -
#747:
TomlGenerator: centralize value termination (writeValueEnd()) to avoid missing/duplicate line feeds - #748: Honor stream-write features changed on generator after creation (follow-up to #734, #735)
-
#750:
TomlGenerator: no flush after close, expose caller's stream as output target, don't mask close failures -
#755:
TomlParser: use a singleStreamReadConstraintssource -
#758:
TomlGenerator: invalid TOML output for root-level values -
#765: Wrong byte position (
byte #-1) in invalid UTF-8 error messages -
#781:
TomlGenerator.writeName(): rejected key leaves generator stuck
-
#873: Fix handling of
@JsonApplyView -
#878: Re-apply entity/DTD hardening after JDK deserialization of
XmlFactory -
#879: Use
Locale.ROOTfor case folding inCaseInsensitiveNameSet -
#882: Translate base64 name-decode errors to
StreamReadException -
#883: Translate
XMLStreamReadercreation errors toStreamReadException -
#886: Escape names already starting with prefix in
Base64NameProcessor -
#887: Apply
XmlNameProcessorto unwrappedObjectNoderoot element name -
#888: Honor
xsi:nilin any attribute position andxs:booleanform -
#890: Update token on 19-digit
longcoercion inisExpectedNumberIntToken -
#893: Decode element name before matching virtual wrapper in
_initStartElement -
#895: Fix leading digit in
AlwaysOnBase64NameProcessorencoded names -
#899: Return
nullfromnextStringValue()at end of input -
#901: Include
ENTITY_REFERENCEreplacement text in element values (instead of silently dropping it) -
#903: Split embedded
]]>across CDATA sections when serializing -
#905: Guard
ToXmlGeneratorcast inserializeWithType()/_serializeObjectId()forconvertValue() -
#907: Recompute XML metadata for filtered props in
XmlBeanSerializerBase -
#909: Clear forced
xsi:typeattribute state inToXmlGenerator.writeName -
#913: Keep
Builder.defaultUseWrapper()from modifying shared introspector -
#918: Apply
XmlNameProcessorconsistently to all written element/attribute names -
#921: Escape colon in XML names written by escaping
XmlNameProcessors
- #713: Misc perf fixes (YAML)
-
#718: Fix
AUTO_CLOSE_SOURCEoverrides and recycled-buffer leaks on read paths -
#722: Use
NumberOutputfor number writes in Properties, TOML and YAML generators -
#749: Fix
YAMLGeneratorflushing/closing ofOutputStreamtarget (follow-up to #735) -
#752:
YAMLGenerator: close target even if writing out buffered content fails with an unchecked exception (follow-up to #749) - #764: Overlong UTF-8 sequences not rejected in YAML
-
#773: Fix a regression: keep
END_OBJECTcurrent for empty YAML documents
- #240: Most types fail to round-trip with default typing enabled; primitive maps silently lose data
-
#251:
Pair/Tripledeserialization fails for raw types and implementation classes (default typing);Tripletread asTripleImpl -
#264: Avoid allocating a
char[]per entry when serializingchar-valued primitive maps -
#270: Use
NumberInputto parse numeric map keys, asjackson-databinddoes
- #38: Support for fastutil collections
-
#2: Better Guava
Multisetserialization / deserialization -
#232: Invalid stringified
Rangeand incomparable sorted elements throw raw runtime exceptions -
#233:
Nulls.SKIPon immutable collection contents dropsnulls returned by value deserializer -
#241:
RangeSetSerializerdoes not implementserializeWithType():RangeSetfails to serialize with default typing -
#242: Guava
ImmutableIntArray/ImmutableLongArray/ImmutableDoubleArrayserializers do not implementserializeWithType() -
#243: Guava
HashCodecannot be deserialized with default typing: type id is non-public subclass -
#244: Guava
Multimap/RangeMap/CachewithObjectvalues serialize each value as{}even when root type is given -
#245:
ImmutableSortedSet/ImmutableSortedMultisetcannot be deserialized asObjectwith default typing -
#253: Avoid redundant copy when deserializing Guava
Multimapalready of requested type -
#256: Avoid boxing every element when deserializing
Ints.asList(etc) primitive lists -
#273: Report
nulls rejected byMultimaps andTables as input mismatch; apply content null handling to single-valueMultimaps -
#274: Report current token to problem handler when value deserializer returns
nullfor structured value
-
#204: Add
Hibernate7Module.Feature.REPLACE_CYCLES_WITH_NULLto handle bi-directional graphs - #205: Update Hibernate version to 7.4.1.Final
- #208: Avoid creating unnecessary temp session
-
#258: Hppc
BitSetserialized up to allocated capacity (size()), not highest set bit -
#260: Specialized
IntIndexedContainerserializer never used (checksJavaType.getClass()instead of raw class) -
#262: Avoid copying
ByteArrayList/CharArrayListcontents on serialization
-
#91: Fail cleanly on non-Object input instead of throwing
NullPointerException
-
#191: Reject malformed zone id suffix in
DateTimeDeserializer -
#192: Resolve
LocalTimetimestamps with the configured time zone -
#193: Reject partial
LocalDateTimearray 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/DateTimefail with raw JodaIllegalArgumentException -
#197:
DateTimeZoneDeserializerleaks rawNumberFormatExceptionfor out-of-int-range timestamp String - #199: Reject timestamp that overflows zone offset in Local* deserializers
-
#200: Reject overflowing period in
IntervalDeserializerinstead of leakingArithmeticException - #202: Use context time zone (not JVM default) for values without offset
-
#203: Reject
DateTime/Instanttext that overflows the Instant range -
#204: Reject out-of-range year for
LocalDate/LocalDateTimeString, Array and key values
-
#90: Fail on non-Object input for
JSONObjectinstead of quietly returning empty Object
- #96: Support embedded binary in Arrays, as already done for Objects
-
#99: Port
JsonPatchSTART_ARRAY check from jsr-353 module
-
#93: Fix
MonetaMoneyModule.getModuleName()returning "JavaxMoneyModule"
-
#229: Add deserializers for PCollection
TreePSet,TreePMap,OrderedPMapandAmortizedPQueuetypes -
#237:
PStack/ConsPStackelement order is reversed on round-trip
- #368: Report property name as found in input in deserialization error paths
- #359: Blackbird rewrite: ClassFile generation of unrolled codec class, optimize record / builder / field
-
#363: Blackbird ignores
@JsonSetter(nulls = Nulls.SKIP)for properties of beans with a properties-based creator - #368: Report property name as found in input in deserialization error paths
-
#69:
ProviderBase.readFrom()fails to advance pastSTART_ARRAYforMappingIteratorwith JSON array input - #77: Minor jetty, jersey test updates
- #78: Upgrade Jersey used for tests from 3.0 to 3.1; remove unused RESTeasy test dependency
-
#234:
ProviderBase.readFrom()fails to advance pastSTART_ARRAYforMappingIteratorwith Array input
-
#223: Reading
List<List<X>>orList<String[]>never returns when an element isn't an array