-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Jackson Release 2.10
Version 2.10 was released on September 26, 2019.
This wiki page gives a list of links to all changes, but there is also a blog entry that covers major features in more detail.
Branch is open for new minor versions
Beyond initial 2.9.0 (described here), following patch releases have been made or are planned:
No changes to minimum JDK baselines for use since 2.9, but 2.10 includes JDK 9+ compliant module-info.class
which should improve forward-compatibility.
Older versions of tools may have issues with this class.
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 runtime environment of JDK/JVM 7 is needed with exception of:
-
jackson-annotations
,jackson-core
,jackson-jr
only require JDK/JVM 6 - Kotlin, Scala and Java 8 modules require JDK/JVM 8 or higher
Enum serialization has changed slightly by introduction of
SerializationFeature.WRITE_ENUM_KEYS_USING_TO_STRING
which takes over SerializationFeature.WRITE_ENUMS_USING_TO_STRING
for specific case of serializing Enum
values of java.util.Map
keys (see databind#2129 for details)
Another functional change is with Java 8 Duration
type, which formerly ignored setting SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS
but now uses it as originally planned (see
java8-modules#75 for details).
With 2.10.0.pr1
we have released following problem reports
Due to changes:
Generic type assignment compatibility is now expected for TypeReference
: so, for example, following code:
MyType value = mapper.readValue(src, new TypeReference<SomeUnrelatedType>() { });
used to compile ok but obviously fail on run type when type cast fails. With 2.10 code will not compile, and that is intentional.
But there is a problem with generic type co-variance (?): although you can assign to subtype like
Map<String, Object> value = mapper.readValue(src, new TypeReference<HashMap<String, Object>() { });
you CAN NOT use subtype of a type variable, so this DOES NOT compile, unfortunately:
Map<String, List<String> value = mapper.readValue(src, new TypeReference<Map<String, ArrayList<String>>() { });
which used to be allowed and actually does work. This is unfortunate, and we are not aware of a way to allow above case.
One thing to note is that this change IS binary-compatible (so anything compiled against 2.9 will still link fine against 2.10), but NOT source-compatible. This means that change should not cause any issues with transitive dependencies; but will cause compilation failure.
I just tried to run my tests. When my application server tried to start, I got errors:
Suppressed: java.lang.RuntimeException: Error scanning entry module-info.class from jar file:/home/ruwen/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.10.0.pr1/jackson-core-2.10.0.pr1.jar
at org.eclipse.jetty.annotations.AnnotationParser.parseJar(AnnotationParser.java:913)
at org.eclipse.jetty.annotations.AnnotationParser.parse(AnnotationParser.java:831)
at org.eclipse.jetty.annotations.AnnotationConfiguration$ParserTask.call(AnnotationConfiguration.java:163)
at org.eclipse.jetty.annotations.AnnotationConfiguration$1.run(AnnotationConfiguration.java:548)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalArgumentException
at org.objectweb.asm.ClassReader.<init>(Unknown Source)
at org.eclipse.jetty.annotations.AnnotationParser.scanClass(AnnotationParser.java:973)
at org.eclipse.jetty.annotations.AnnotationParser.parseJarEntry(AnnotationParser.java:956)
at org.eclipse.jetty.annotations.AnnotationParser.parseJar(AnnotationParser.java:909)
... 6 more
11:05 xxx@yyy:~$ java -version
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (build 1.8.0_212-8u212-b03-2~deb9u1-b03)
OpenJDK 64-Bit Server VM (build 25.212-b03, mixed mode)
The blame was on an older version of Jetty. Since this was used only in test, the version was quite old. But other people might get similar problems with byte-code manipulating libraries.
First official version of the jackson-datatype-eclipse-collections
(for Eclipse Collections was introduced in 2.10 (preview version included since 2.9.5)
Much of additional functionality mirrors changes that 3.0 developments are making, in form that will get some of the benefits, and should ease migration to 3.0.
Due to numerous CVEs for one specific kind of Polymorphic Deserialization (see this blog post for details), block-list approach has proven insufficient to prevent issues.
As a result, #2195 -- add abstraction PolymorphicTypeValidator
, for limiting allowed polymorphic subtypes -- was added.
Although full moved to immutable factories, mappers, by (only) using builder-style construction will only be included in 3.0, 2.10 does introduce builder-pattern itself (but does not force strict immutability beyond what 2.x API supports). The main benefits of this addition are:
- Easier migration to 3.0 since change to builder-based construction can be made in 2.10 already
- More convenient configurability; ability to expose format-specific configuration beyond simple on/off features
Example of builder style:
JsonFactory f = JsonFactory.builder()
// Change per-factory setting to prevent use of `String.intern()` on symbols
.disable(JsonFactory.Feature.INTERN_FIELD_NAMES, false)
// Disable json-specific setting to produce non-standard "unquoted" field names:
.disable(JsonWriteFeature.QUOTE_FIELD_NAMES, true)
.build();
ObjectMapper mapper = JsonMapper.builder(f)
.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false)
.build();
Another change geared towards 3.0 compatibility is the creation of 4 new format feature types, to replace 2 existing features (JsonParser.Feature
, JsonGenerator.Feature
):
-
StreamReadFeature
: format-agnostic (general) features for stream readers (parsers) -
StreamWriteFeature
: format-agnostic (general) features for stream writers (generators) -
JsonReadFeature
: JSON-specific stream reader (parser) features -
JsonWriteFeature
: JSON-specific stream writer (generator) features
For 2.10 these features will act as aliases to matching JsonParser.Feature
s and JsonGenerator.Feature
s: in 3.0 they will be the only stream-level features (JsonParser.Feature
s, JsonGenerator.Feature
being removed)
Example of using new configuration features:
JsonFactory f = JsonFactory.builder()
.disable(JsonWriteFeature.QUOTE_FIELD_NAMES, true)
.build();
All standard components will include module-info.class
, generated using Moditect Maven plug-in.
Resulting jars will therefore have proper module information for Java 9 and beyond but still be usable on JDK 7 (or, in case of jackson-core
and jackson-annotations
, JDK 6)
Beyond core functionality most modules got some updates; here's a sampling of most notable
Root value sequence reading; reading typed Map
s; ability to plug-in custom ValueReader
s and ValueWriter
s (similar to databind JsonSerializer
, JsonDeserializer
A bunch of fixes, plus support of XML Schema xsi:nil
concept.
- #138: Add basic Java 9+ module info
-
#141: Add
JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES
-
#159: Add
JsonFormat.Shape.BINARY
- #433: Add Builder pattern for creating configured Stream factories
-
#464: Add "maximum unescaped char" configuration option for
JsonFactory
via builder -
#467: Create
JsonReadFeature
to move JSON-specificJsonParser.Feature
s to - #479: Improve thread-safety of buffer recycling
-
#480:
SerializableString
value can not directly render to Writer -
#481: Create
JsonWriteFeature
to move JSON-specificJsonGenerator.Feature
s to -
#484: Implement
UTF8JsonGenerator.writeRawValue(SerializableString)
(andwriteRaw(..)
) more efficiently -
#495: Create
StreamReadFeature
to move non-json specificJsonParser.Feature
s to -
#496: Create
StreamWriteFeature
to take over non-json-specificJsonGenerator.Feature
s -
#502: Make
DefaultPrettyPrinter.createInstance()
to fail for sub-classes -
#506: Add missing type parameter for
TypeReference
inObjectCodec
-
#508: Add new exception type
InputCoercionException
to be used for failed coercions like overflow forint
-
#517: Add
JsonGenerator.writeStartObject(Object, int)
(needed by CBOR, maybe Avro) - #527: Add simple module-info for JDK9+, using Moditect
- #533: UTF-8 BOM not accounted for in JsonLocation.getByteOffset()
-
#539: Reduce max size of recycled byte[]/char[] blocks by
TextBuffer
,ByteArrayBuilder
-
#547:
CharsToNameCanonicalizer
: Internal error onSymbolTable.rehash()
with high number of hash collisions - #548: ByteQuadsCanonicalizer: ArrayIndexOutOfBoundsException in addName
- #549: Add configurability of "quote character" for JSON factory
- #561: Misleading exception for unquoted String parsing
- #563: Async parser does not keep track of Array context properly
-
#18: Make
JsonNode
serializable -
#1675: Remove "impossible"
IOException
inreadTree()
andreadValue()
ObjectMapper
methods which accept Strings -
#1954: Add Builder pattern for creating configured
ObjectMapper
instances- also add
JsonMapper
as explicit type, through which builders are created and that exposes JSON-specific configuration
- also add
-
#1995: Limit size of
DeserializerCache
, auto-flush on exceeding -
#2059: Remove
final
modifier forTypeFactory
-
#2077:
JsonTypeInfo
with a subtype havingJsonFormat.Shape.ARRAY
and no fields generates{}
not[]
-
#2115: Support naive deserialization of
Serializable
values as "untyped", same asjava.lang.Object
- #2116: Make NumberSerializers.Base public and its inherited classes not final
-
#2126:
DeserializationContext.instantiationException()
throwsInvalidDefinitionException
-
#2129: Add
SerializationFeature.WRITE_ENUM_KEYS_USING_INDEX
, separate from value setting -
#2149: Add
MapperFeature.ACCEPT_CASE_INSENSITIVE_VALUES
-
#2153: Add
JsonMapper
to replace genericObjectMapper
usage -
#2187: Make
JsonNode.toString()
use sharedObjectMapper
to produce valid json -
#2195: Add abstraction
PolymorphicTypeValidator
, for limiting subtypes allowed by default typing,@JsonTypeInfo
-
#2204: Add
JsonNode.isEmpty()
as convenience alias -
#2211: Change of behavior (2.8 -> 2.9) with
ObjectMapper.readTree(input)
with no content -
#2220: Force serialization always for
convertValue()
; avoid short-cuts -
#2223: Add
missingNode()
method inJsonNodeFactory
-
#2230:
WRITE_BIGDECIMAL_AS_PLAIN
is ignored if@JsonFormat
is used -
#2236: Type id not provided on
Double.NaN
,Infinity
with@JsonTypeInfo
- #2237: JsonNode improvements: "required"
-
#2241: Add
PropertyNamingStrategy.LOWER_DOT_CASE
for dot-delimited names - #2273: Add basic Java 9+ module info
- #2309: READ_ENUMS_USING_TO_STRING doesn't support null values
-
#2331:
JsonMappingException
through nested getter with generic wildcard return type -
#2336:
MapDeserializer
can not mergeMap
s with polymorphic values -
#2348: Add sanity checks for
ObjectMapper.readXXX()
methods -
#2390:
Iterable
serialization breaks when adding@JsonFilter
annotation -
#2392:
BeanDeserializerModifier.modifyDeserializer()
not applied to custom bean deserializers -
#2393:
TreeTraversingParser.getLongValue()
incorrectly checkscanConvertToInt()
-
#2398: Replace recursion in
TokenBuffer.copyCurrentStructure()
with iteration -
#2415: Builder-based POJO deserializer should pass builder instance, not type, to
handleUnknownVanilla()
-
#2416: Optimize
ValueInstantiator
construction for defaultCollection
,Map
types -
#2422:
scala.collection.immutable.ListMap
fails to serialize since 2.9.3 -
#2424: Add global config override setting for
@JsonFormat.lenient()
-
#2430: Change
ObjectMapper.valueToTree()
to convertnull
toNullNode
- #2432: Add support for module bundles
-
#2442:
ArrayNode.addAll()
adds rawnull
values which cause NPE ondeepCopy()
-
#2458:
Nulls
property metadata ignored for creators -
#2467: Accept
JsonTypeInfo.As.WRAPPER_ARRAY
with no second argument to deserialize as "null value"
-
#168:
JsonMappingException
for union types with multiple Record types - #174: Improve Union type serialization performance
- #177: Deserialization of "empty" Records as root values fails
- #139: Incorrect decimal fraction representation
- #155: Inconsistent support for FLUSH_PASSED_TO_STREAM
-
#108: Add new
CsvParser.Feature.ALLOW_COMMENTS
to replace use of deprecatedJsonParser.Feature.ALLOW_YAML_COMMENTS
-
#134:
CSVParserBootstrapper
createsUTF8Reader
which is incorrectly not auto-closed (reported by iuliu-b@github)
- #100: Add an option to specify properties prefix
-
#139: Support for Map<String, String> in
JavaPropsMapper
-
#148: Add
ProtobufMapper.generateSchemaFor(TypeReference<?>)
overload
- #242: Deserialization of class inheritance depends on attributes order
- #336: WRITE_BIGDECIMAL_AS_PLAIN Not Used When Writing Pretty
- #350: Wrap Xerces/Stax (JDK-bundled) exceptions during parser initialization
- #351: XmlBeanSerializer serializes AnyGetters field even with FilterExceptFilter
-
#354: Support mapping
xsi:nil
marked elements asnull
s (JsonToken.VALUE_NULL
)
- #50: Empty string serialized without quotes if MINIMIZE_QUOTES is enabled
- #101: Use latest SnakeYAML version 1.24 and get rid of deprecated methods
- #116: Error handling "null" String when Feature.MINIMIZE_QUOTES is active
- #129: Convert YAML string issue
-
#140: Implement
JsonGenerator.writeFieldId(...)
forYAMLGenerator
- #34: (guava) Allow use of Guava versions up to 25 (from 22)
- #37: (eclipse-collections) Implement pair deserialization
- #48: (all) Add simple module-info for JDK9+, using Moditect
-
#50: (guava) Add Serializer and Deserializer for
RangeSet
-
#53: (guava) GuavaImmutableCollectionDeserializer
cannot deserialize an empty
Optional` from null - #56: (guava) Range property name (de)serialisation doesn't respect property naming strategy
-
#58: (guava) Drop support for Guava v10 - v13 to simplify
RangeFactory
-
#125: Ignore missing entities when lazy loading is enabled, if newly added
Feature.WRITE_MISSING_ENTITIES_AS_NULL
is enabled
-
#239: Auto-detect sealed classes (similar to
@JsonSubTypes
)
Full support for Scala 2.13 (and still supports 2.10, 2.11, 2.12). Fixes from 2.9.10 merged, plus:
- (via
databind#2422
)scala.collection.immutable.ListMap
fails to serialize since 2.9.3
-
#51: (datetime)
YearKeyDeserializer
doesn't work with non-padded year values -
#69: (datetime)
ZonedDateTime
for times before the epoch do not serialize correctly -
#75: (datetime) Use
SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS
for configuringDuration
serialization - #82: (datetime) Typo in YearMothKeyDeserializer class name
-
#105:
LocalTime
should generate "time" schema instead of "date-time" -
#121: Array representation of
MonthDay
can not be deserialized - #126: Change auto-registration in 2.10 to provide "new" (JavaTimeModule) instead of legacy module
-
#129: Support
lenient
setting withLocalDateDeserializer
- #52: Interfaces may have non-abstract methods (since java8)
- #111: AnnotationBundleKey equality fails for Parameter Annotations
- #60: Add support for reading "root value" streams (linefeed separated/concatenated)
-
#63: Change default for
JSON.Feature.USE_FIELDS
totrue
(from false) in 2.10 - #65: Allow registration of custom readers, writers (to support 3rd party, custom types)
-
#66: Add
Json.mapOfFrom(Class)
to support binding POJO-valued maps