-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Jackson Release 2.12
Jackson Version 2.12 was released on November 28, 2020: two release candidates (2.12.0-rc1
, 2.12.0-rc2
) were released prior to the final 2.12.0.
This wiki page gives a list of links to all changes (with brief descriptions) included.
Aside from detailed change notes below, there is a separate 2.12 Acknowledgements page for special thanks.
Branch is nominally open but it is not likely that there will be full patch releases beyond (2.12.7). Micro-patches are possible.
- 2.12.1 (08-Jan-2021)
- 2.12.2 (03-Mar-2021)
- 2.12.3 (12-Apr-2021)
- 2.12.4 (06-Jul-2021)
- 2.12.5 (27-Aug-2021)
- 2.12.6 (15-Dec-2021)
- 2.12.7 (26-May-2022)
Following micro-patches have been released:
-
jackson-databind
2.12.6.1
(26-Mar-2022) -- withjackson-bom
version2.12.6.20220326
- #2816: Optimize UntypedObjectDeserializer wrt recursion (CVE-2020-36518)
-
jackson-databind
2.12.7.1
(12-Oct-2022) -- withjackson-bom
version2.12.7.20221012
-
jackson-databind
2.12.7.2
(02-May-2024) -- withjackson-bom
version2.12.7.20240502
-
#3275: JDK 16 Illegal reflective access for
Throwable.setCause()
withPropertyNamingStrategy.UPPER_CAMEL_CASE
-
#3275: JDK 16 Illegal reflective access for
JDK baseline for use since 2.11 is retained with following exceptions:
-
Ion
dataformat module (part ofjackson-dataformats-binary
) now requires Java 8 due to new optionalIonJavaTimeModule
-
Eclise-collections
datatype module (part ofjackson-datatypes-collections
) requires Java 8 (was the case before but not documented) -
Guava
datatype module (part ofjackson-datatypes-collections
) requires Java 8 due to Guava 21 dependency upgrades baseline
JDK 8 is required to build all components, however, as module info inclusion plug-in requires it (note: publishing to Maven Central also requires JDK 8), but the minimum runtime version is JDK/JVM 7, with following exceptions:
-
jackson-annotations
,jackson-core
,jackson-jr
only require JDK/JVM 6 - JDK/JVM 8 higher needed for:
- Kotlin and Scala language modules
- Java 8 modules (datatypes, parameter-names, jsr310 date/time)
- Ion dataformat module
- Eclipse-collections datatype module
Due to use of java.util.Objects
, part of JDK 7, minimum Android version supported appears to be 4.4 / API Level 19:
https://developer.android.com/reference/kotlin/java/util/Objects
Jackson Kotlin module is now compiled against (and is designed to work with) Kotlin 1.4.
Support for Scala 2.10 is dropped (so that Jackson 2.11 is the last version of with Scala 2.10 support): Jackson 2.12 will support following Scala versions:
- 2.11
- 2.12
- 2.13
Addition of explicit support for java.lang.Record
changes handling slightly for one specific case: if you have a Record
type with 1 property, like:
public record MyValueRecord(String value) {}
it would be assumed to use "Delegating" style of parameter passing, and would (only) accept JSON String to bind. With 2.12 all Records
default to "Properties" style binding so a single-property JSON Object is expected instead. Note that it is possible to annotate constructor explicitly:
public record MyValueRecord(String value) {
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public MyValueRecord(String value) {
this.value = value;
}
}
to produce pre-2.12 behavior, as necessary. See jackson-databind#2980 for details.
Default for FromXmlParser.Feature.EMPTY_ELEMENT_AS_NULL
changed from true
(2.9 - 2.11) to false
, so that no automatic coercion done from empty elements like <empty/>
into null
It also looks like handling of "empty values" (zero-length String) for scalar values like numbers changed, as per jackson-dataformat-xml#473, but this issue should be resolved in 2.12.4.
- Input
null
value will be deserialized asJsonValue.NULL
- see datatypes-misc#2
- New Base module -- jackson-datatype-blackbird
- (Future) Replacement for Afterburner module: solves same use case, speeding up of POJO databind
- Works better than Afterbuern with newer JVMs (Java 9 and later)
- Contributed by Steven Schlansker (@stevenschlansker)
- Alternate jars with
jakarta
classifier for modules that rely on JAX-xxx APIs, to support new "Jakarta" namespaced apis:- JAX-RS modules (
jackson-jaxrs-XXX-provider
) and JAXB annotations module (jackson-module-jaxb-annotations
) have both "regular" jar and variant with classifier ofjakarta
- Existing ("old") jars rely on 2.x version of JAX-WS, JAX-RS APIs, in existing
javax.
namespace - New "jakarta" variants (with classifier of
jakarta
) will refer to repackaged "Jakarta" variants of APIs - Users will need to specify classifier, for now, if they want/need to use newer dependencies
- JAX-RS modules (
#2113 adds CoercionConfig
system which allows indicating which of 4 CoercionAction
s to take for given input shape, target type:
-
Fail
: not allowed, throw exception -
AsNull
: allow, coerce tonull
(although may be further mapped via other mechanisms) -
AsEmpty
: allow, coerce to "empty" value of type (emptyCollection
, POJO with no properties set) -
TryConvert
: allow if there is logical conversion (for example String "123" can be parsed, converted toint
value123
)
Input shapes are defined with CoercionInputShape
enum which roughly corresponds to JsonToken
values, but also has 3 logical types for "empty" String, Array and Object as special cases.
Target type is specific both by concrete (specific type), Class
and new LogicalType
that has a smaller set of values.
Rules can be targeted at 3 levels:
- For specific concrete type (
Class
), input shape - For logical type (like
LogicalType.Boolean
) -- coversboolean
,Boolean
, elements inboolean[]
,AtomicBoolean
-- and input shape - Default action for coercions from input shape, used if no per-type (concrete or logical) specified -- most commonly used for input shape of
EmptyString
This feature allows defining coercion rules like:
- Let empty String value become POJO similar to being deserialized from
{ }
JSON Input (especially useful for XML) - Let empty String value become
null
for specified type(s) - Prevent coercion from JSON Numbers into Java
boolean
s (by default non-zero JSON Integers map to Boolean values astrue
)
This is issue databind#1296: explained in bit more detail on Jackson 2.12: @JsonIncludeProperties blog post
- Support for "Arrays" with Tree Model,
JsonNode
, "untyped"/List
/Map
(nominaljava.lang.Object
)-
dataformat-xml#205:
XmlMapper
/UntypedObjectDeserializer
swallows duplicated elements in -
dataformat-xml#403: Make
JsonNode
implicitly createArrayNode
s for repeated XML Elements (aka "Make JsonNode work with XML")
-
dataformat-xml#205:
- Basic support for "Mixed Content" (element(s) AND text for given XML element)
-
dataformat-xml#405: Mixed content not exposed through
FromXmlParser
, lost byJsonNode
- As with array support, usable via
JsonNode
and "untyped" (Map
/List
/Object
) - Does not retain full ordering so further work needed for 100% high fidelity mapping
-
dataformat-xml#405: Mixed content not exposed through
- Fully support root values, including scalar types
-
dataformat-xml#121:
XmlMapper
not deserializing root-level Enums - dataformat-xml#254: No String-argument constructor/factory method to deserialize from String value when it is a Integer
-
dataformat-xml#412: Coercion from element-with-attribute-and-text only works for
String
, not other scalar types
-
dataformat-xml#121:
- Support deserialization of scalars even for elements that contain additional attributes
Pretty much as expected, see https://github.com/FasterXML/jackson-databind/issues/2709 for details:
reading and writing of java.lang.Record
should work when running on Java 14 or later, using expected accessors,
constructors, and annotation overrides (if any).
The oldest open issue, databind#43 is now implemented.
It basically allows omitting of actual Type Id field or value, as long as the subtype can be deduced
(@JsonTypeInfo(use=DEDUCTION)
) from existence of fields. That is, every subtype has a distinct set of fields they included, and so during deserialization type can be uniquely and reliably detected.
See Jackson 2.12: Deduction-based Polymorphism for longer explanation.
Issue databind#1498 addresses one remaining case where Creator (constructor) auto-detection was not possible: that of single-argument Constructors (due to ambiguity between Properties-based and Delegating choices).
2.12 allows configuration of ContructorDetector
to resolve this aspect.
See Jackson 2.12: ConstructorDetector
for longer explanation.
-
dataformats-binary#213: There is new optional
IonJavaTimeModule
that allows use of native Ion datatypes with Java 8 Date/Time types (JSR-310)
-
JsonNodeFeature
/-Config
JSTEP-3: configuring reading/writing ofJsonNode
-
@PreSerialize
/@PostDeserialize
method annotations (https://github.com/FasterXML/jackson-databind/issues/2045) - Other format module fixes:
- Protobuf: proto3, use of Wire/schema for protoc parsing
- CSV, structured?
- Logical types: Avro, CBOR
-
#171:
JsonSubType.Type
should accept array of names - #173: Jackson version alignment with Gradle 6
-
#174: Add
@JsonIncludeProperties
-
#175: Add
@JsonTypeInfo(use=DEDUCTION)
-
#177: Ability to use
@JsonAnyGetter
on fields -
#179: Add
@JsonKey
annotation -
#180: Allow repeated calls to
SimpleObjectIdResolver.bindItem()
for same mapping -
#181: Add
namespace
property for@JsonProperty
(for XML module)
-
#500: Allow "optional-padding" for
Base64Variant
-
#573: More customizable TokenFilter inclusion (using
Tokenfilter.Inclusion
) - #618: Publish Gradle Module Metadata
-
#619: Add
StreamReadCapability
for further format-based/format-agnostic handling improvements -
#627: Add
JsonParser.isExpectedNumberIntToken()
convenience method -
#630: Add
StreamWriteCapability
for further format-based/format-agnostic handling improvements -
#631: Add
JsonParser.getNumberValueExact()
to allow precision-retaining buffering -
#639: Limit initial allocated block size by
ByteArrayBuilder
to max block size
-
#43: Add option to resolve type from multiple existing properties,
@JsonTypeInfo(use=DEDUCTION)
- #921: Deserialization Not Working Right with Generic Types and Builders
-
#1296: Add
@JsonIncludeProperties(propertyNames)
(reverse of@JsonIgnoreProperties
) -
#1458:
@JsonAnyGetter
should be allowed on a field - #1498: Allow handling of single-arg constructor as property based by default
-
#1852: Allow case insensitive deserialization of String value into
boolean
/Boolean
(esp for Excel) -
#1886: Allow use of
@JsonFormat(with=JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)
on Class - #1919: Abstract class included as part of known type ids for error message
-
#2091:
ReferenceType
does not expose valid containedType -
#2113: : Add
CoercionConfig[s]
mechanism for configuring allowed coercions -
#2118:
JsonProperty.Access.READ_ONLY
does not work with "getter-as-setter"Collection
s -
#2215: Support
BigInteger
andBigDecimal
creators inStdValueInstantiator
-
#2283:
JsonProperty.Access.READ_ONLY
fails with collections when a property name is specified -
#2675: Support use of
Void
valued properties (MapperFeature.ALLOW_VOID_VALUED_PROPERTIES
) -
#2683: Explicitly fail (de)serialization of
java.time.*
types in absence of registered custom (de)serializers -
#2707: Improve description included in by
DeserializationContext.handleUnexpectedToken()
- #2709: Support for JDK 14 record types
-
#2715:
PropertyNamingStrategy
class initialization depends on its subclass, this can lead to class loading deadlock -
#2719:
FAIL_ON_IGNORED_PROPERTIES
does not throw onREADONLY
properties with an explicit name - #2726: Jackson version alignment with Gradle 6
-
#2732: Allow
JsonNode
auto-convert intoArrayNode
if duplicates found (for XML) -
#2733: Allow values of "untyped" auto-convert into
List
if duplicates found (for XML) -
#2775: Disabling
FAIL_ON_INVALID_SUBTYPE
breaks polymorphic deserialization of Enums -
#2804: Throw
InvalidFormatException
instead ofMismatchedInputException
for ACCEPT_FLOAT_AS_INT coercion failures -
#2871: Add
@JsonKey
annotation (similar to@JsonValue
) for customizable serialization of Map keys -
#2873:
MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS
should work for enum as keys - #2879: Add support for disabling special handling of "Creator properties" wrt alphabetic property ordering
-
#2885: Add
JsonNode.canConvertToExactIntegral()
to indicate whether floating-point/BigDecimal values could be converted to integers losslessly - #2895: Improve static factory method generic type resolution logic
-
#2909:
@JsonValue
not considered when evaluating inclusion - #2910: Make some java platform modules optional
-
#2925: Add support for serializing
java.sql.Blob
-
#2928:
AnnotatedCreatorCollector
should avoid processing synthetic static (factory) methods - #2932: Problem with implicit creator name detection for constructor detection
-
#222: Add
CBORGenerator.Feature.LENIENT_UTF_ENCODING
for lenient handling of Unicode surrogate pairs on writing - #228: Add support for decoding unassigned "simple values" (type 7)
- #199: Empty Lists can only be String-typed in CSV
-
#222:
JsonParser.Feature.EMPTY_STRING_AS_NULL
does not work when text is parsed asString[]
-
#212: Optimize
IonParser.getNumberType()
usingIonReader.getIntegerSize()
-
#213: Add support to (de)serialize Ion timestamps to/from
java.time
classes
- #97: Weird Exception during read with Type info
-
#121:
XmlMapper
not deserializing root-level Enums -
#124: Deserialization of an empty list (with empty XML tag) results in
null
-
#205:
XmlMapper
/UntypedObjectDeserializer
swallows duplicated elements in XML documents - #226: XML to JSON - IOException when parsing XML with XMLMapper
-
#252: Empty (or self-closing) Element representing
List
is incorrectly deserialized as null, not Empty List - #254: No String-argument constructor/factory method to deserialize from String value when it is a Integer
-
#257: Deserialization fails of lists containing elements with
xml:space
attribute -
#262: Make
ToXmlGenerator
non-final - #273: Input mismatch with case-insensitive properties
- #307: Missing collection item when they are not wrapped during unmarshal with multiple namespaces
- #314: Jackson gets confused by parent list element
-
#318:
XMLMapper
fails to deserialize null (POJO reference) from blank tag -
#319: Empty root tag into
List
deserialization bug -
#360: Add a feature to support writing
xsi:nil
attribute fornull
values -
#374: Deserialization fails with
XmlMapper
andDeserializationFeature.UNWRAP_ROOT_VALUE
-
#377:
ToXmlGenerator
ignoresBase64Variant
while serializingbyte[]
-
#380: Unable to deserialize root-level
Instant
value from XML - #390: Unexpected attribute at string fields causes extra objects to be created in parent list
-
#397:
XmlReadContext
does not keep track of array index -
#403: Make
JsonNode
implicitly createArrayNode
s for repeated XML Elements -
#405: Mixed content not exposed through
FromXmlParser
, lost byJsonNode
-
#411: Change default setting of
FromXmlParser.Feature.EMPTY_ELEMENT_AS_NULL
fromtrue
tofalse
-
#412: Coercion from element-with-attribute-and-text only works for
String
not other scalar types - #422: Elements containing parsed incorrectly when at the end of another element
-
#434: Add missing
ElementType.ANNOTATION_TYPE
for Jackson xml annotations to allow bundling - Add Gradle Module Metadata (https://blog.gradle.org/alignment-with-gradle-module-metadata)
- Upgrade Woodstox dependency to 6.2.3 (<- 6.2.1)
- #71: Hex number as an entry of an Object causing problem(s) with binding to POJO
-
#130: Empty String deserialized as
null
instead of empty string -
#175: Add
YAMLGenerator.Feature.INDENT_ARRAYS_WITH_INDICATOR
to indent by 2 spaces - #226: Quote 'y'/'Y'/'n'/'N' as names too (to avoid problems with Boolean keys)
- #229: Allow configuring the way "must quote" is determined for property names, String values
-
#231: Typed object with anchor throws Already had POJO for id (note: actual fix in
jackson-annotations
) - #232: Typed object throws "Missing type id" when annotated with '@JsonIdentityInfo'
- #233: Support decoding Binary, Octal and Hex numbers as integers
- #25: (guava) SetMultimap should be deserialized to a LinkedHashMultimap by default
- #79: (guava) Guava's RangeHelper causing NPE in PropertyNamingStrategy
- (guava) Update "preferred" Guava version to 21.0
- (guava) Require Java 8 due to Guava 21 baseline (JRE variant)
-
#136: Add feature
WRAP_IDENTIFIER_IN_OBJECT
to allow disabling of wrapping of "id" attribute
- #94: Deserialization of timestamps with UTC timezone to LocalDateTime doesn't yield correct time
- #165: Problem in serializing negative Duration values
-
#166: Cannot deserialize
OffsetDateTime.MIN
orOffsetDateTime.MAX
withADJUST_DATES_TO_CONTEXT_TIME_ZONE
enabled -
#175: ObjectMapper#setTimeZone ignored by jsr-310/datetime types during serialization when using
@JsonFormat
annotation -
#184:
DurationDeserializer
should use@JsonFormat.pattern
(and config override) to support configurableChronoUnit
-
#189: Support use of "pattern" (
ChronoUnit
) forDurationSerializer
too
- #116: Improve schema support for DateTimeZone type
- #117: Timestamp deserialization not working for CSV, Properties or XML
-
#117: Use of
ToStringSerializer
via@JsonSerialize
onint
/long
property does not work -
#118: Using
@JsonFormat(shape = JsonFormat.Shape.STRING)
onint
,long
properties not working
-
#115: Remove
java.beans.Introspector
dependency from JAXB module (to get rid ofjava.desktop
module dep) -
#116: Jakarta Namespace Support
- See notes earlier on "Jakarta" variants of module jars: users will need to opt-in by using Maven classifier
jakarta
for version with "new" JAX-WS/JAXB dependencies
- See notes earlier on "Jakarta" variants of module jars: users will need to opt-in by using Maven classifier
- #100: Prevent "double-prefixing" Mr Bean generated classes
- #322: Added extension methods to SimpleModule addSerializer and addDeserializer to support KClass arguments that register the serializer/deserializer for both the java type and java class.
- #356: Kotlin 1.4 support
- #385: Add Moditect, source module info, to allow Kotlin module usage with Java Module system
- Add Gradle Module Metadata (https://blog.gradle.org/alignment-with-gradle-module-metadata)
- #370: Support jackson feature @JsonMerge
-
#449: Remove
jackson-module-paranamer
dependency. Scala 2.11 variant uses Paranamer directly still but Scala 2.12 and 2.13 releases no longer use Paranamer. -
#455: get
ScalaAnnotationIntrospector
to ignore non-Scala classes - #462: Unable to deserialize Seq or Map with AS_EMPTY null handling
-
#466: Add support for
WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED
- #467: Serializer for Scala Iterable/Iterator converts to Java Collection - avoid this conversion
- #480: Drop Scala 2.10 support