Skip to content

Commit 3c98f20

Browse files
committed
Merge branch '2.x' into 3.x
2 parents ed8fa24 + 961892d commit 3c98f20

File tree

3 files changed

+51
-46
lines changed

3 files changed

+51
-46
lines changed

release-notes/VERSION-2.x

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Project: jackson-databind
2121
#5179: Add "current token" info into `MismatchedInputException`
2222
- Generate SBOMs [JSTEP-14]
2323
24-
2.19.1 (not yet released)
24+
2.19.1 (13-Jun-2025)
2525
2626
#5139: In `CollectionDeserializer`, `JsonSetter.contentNulls` is sometimes ignored
2727
(contributed by @wrongwrong)

src/main/java/tools/jackson/databind/deser/jdk/EnumMapDeserializer.java

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -246,9 +246,6 @@ public EnumMap<?,?> deserialize(JsonParser p, DeserializationContext ctxt,
246246
// [databind#631]: Assign current value, to be accessible by custom deserializers
247247
p.assignCurrentValue(result);
248248

249-
final ValueDeserializer<Object> valueDes = _valueDeserializer;
250-
final TypeDeserializer typeDeser = _valueTypeDeserializer;
251-
252249
String keyStr;
253250
if (p.isExpectedStartObjectToken()) {
254251
keyStr = p.nextName();
@@ -289,10 +286,8 @@ public EnumMap<?,?> deserialize(JsonParser p, DeserializationContext ctxt,
289286
continue;
290287
}
291288
value = _nullProvider.getNullValue(ctxt);
292-
} else if (typeDeser == null) {
293-
value = valueDes.deserialize(p, ctxt);
294289
} else {
295-
value = valueDes.deserializeWithType(p, ctxt, typeDeser);
290+
value = _deserializeNoNullChecks(p, ctxt);
296291
}
297292
} catch (Exception e) {
298293
return wrapAndThrow(ctxt, e, result, keyStr);
@@ -380,10 +375,8 @@ public EnumMap<?,?> _deserializeUsingProperties(JsonParser p, DeserializationCon
380375
continue;
381376
}
382377
value = _nullProvider.getNullValue(ctxt);
383-
} else if (_valueTypeDeserializer == null) {
384-
value = _valueDeserializer.deserialize(p, ctxt);
385378
} else {
386-
value = _valueDeserializer.deserializeWithType(p, ctxt, _valueTypeDeserializer);
379+
value = _deserializeNoNullChecks(p, ctxt);
387380
}
388381
} catch (Exception e) {
389382
wrapAndThrow(ctxt, e, _containerType.getRawClass(), keyName);
@@ -400,4 +393,20 @@ public EnumMap<?,?> _deserializeUsingProperties(JsonParser p, DeserializationCon
400393
return null;
401394
}
402395
}
396+
397+
/**
398+
* Deserialize the content of the map.
399+
* If _valueTypeDeserializer is null, use _valueDeserializer.deserialize; if non-null,
400+
* use _valueDeserializer.deserializeWithType to deserialize value.
401+
* This method only performs deserialization and does not consider _skipNullValues, _nullProvider, etc.
402+
* @since 2.19.2
403+
*/
404+
protected Object _deserializeNoNullChecks(JsonParser p, DeserializationContext ctxt)
405+
throws JacksonException
406+
{
407+
if (_valueTypeDeserializer == null) {
408+
return _valueDeserializer.deserialize(p, ctxt);
409+
}
410+
return _valueDeserializer.deserializeWithType(p, ctxt, _valueTypeDeserializer);
411+
}
403412
}

src/main/java/tools/jackson/databind/deser/jdk/MapDeserializer.java

Lines changed: 32 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -322,9 +322,11 @@ public ValueDeserializer<?> createContextual(DeserializationContext ctxt,
322322
if (ignorals != null) {
323323
Set<String> ignoresToAdd = ignorals.findIgnoredForDeserialization();
324324
if (!ignoresToAdd.isEmpty()) {
325-
ignored = (ignored == null) ? new HashSet<String>() : new HashSet<String>(ignored);
326-
for (String str : ignoresToAdd) {
327-
ignored.add(str);
325+
if (ignored == null) {
326+
ignored = new HashSet<>(ignoresToAdd);
327+
} else {
328+
ignored = new HashSet<String>(ignored);
329+
ignored.addAll(ignoresToAdd);
328330
}
329331
}
330332
}
@@ -478,8 +480,6 @@ public Object deserializeWithType(JsonParser p, DeserializationContext ctxt,
478480
@SuppressWarnings("unchecked")
479481
public final Class<?> getMapClass() { return (Class<Map<Object,Object>>) _containerType.getRawClass(); }
480482

481-
@Override public JavaType getValueType() { return _containerType; }
482-
483483
/*
484484
/**********************************************************************
485485
/* Internal methods, non-merging deserialization
@@ -489,12 +489,8 @@ public Object deserializeWithType(JsonParser p, DeserializationContext ctxt,
489489
protected final Map<Object,Object> _readAndBind(JsonParser p, DeserializationContext ctxt,
490490
Map<Object,Object> result) throws JacksonException
491491
{
492-
final KeyDeserializer keyDes = _keyDeserializer;
493-
final ValueDeserializer<Object> valueDes = _valueDeserializer;
494-
final TypeDeserializer typeDeser = _valueTypeDeserializer;
495-
496492
MapReferringAccumulator referringAccumulator = null;
497-
boolean useObjectId = valueDes.getObjectIdReader(ctxt) != null;
493+
boolean useObjectId = _valueDeserializer.getObjectIdReader(ctxt) != null;
498494
if (useObjectId) {
499495
referringAccumulator = new MapReferringAccumulator(_containerType.getContentType().getRawClass(),
500496
result);
@@ -515,7 +511,7 @@ protected final Map<Object,Object> _readAndBind(JsonParser p, DeserializationCon
515511
}
516512

517513
for (; keyStr != null; keyStr = p.nextName()) {
518-
Object key = keyDes.deserializeKey(keyStr, ctxt);
514+
Object key = _keyDeserializer.deserializeKey(keyStr, ctxt);
519515
// And then the value...
520516
JsonToken t = p.nextToken();
521517
if ((_inclusionChecker != null) && _inclusionChecker.shouldIgnore(keyStr)) {
@@ -530,10 +526,8 @@ protected final Map<Object,Object> _readAndBind(JsonParser p, DeserializationCon
530526
continue;
531527
}
532528
value = _nullProvider.getNullValue(ctxt);
533-
} else if (typeDeser == null) {
534-
value = valueDes.deserialize(p, ctxt);
535529
} else {
536-
value = valueDes.deserializeWithType(p, ctxt, typeDeser);
530+
value = _deserializeNoNullChecks(p, ctxt);
537531
}
538532
if (useObjectId) {
539533
referringAccumulator.put(key, value);
@@ -560,10 +554,8 @@ protected final Map<Object,Object> _readAndBind(JsonParser p, DeserializationCon
560554
protected final Map<Object,Object> _readAndBindStringKeyMap(JsonParser p, DeserializationContext ctxt,
561555
Map<Object,Object> result) throws JacksonException
562556
{
563-
final ValueDeserializer<Object> valueDes = _valueDeserializer;
564-
final TypeDeserializer typeDeser = _valueTypeDeserializer;
565557
MapReferringAccumulator referringAccumulator = null;
566-
boolean useObjectId = (valueDes.getObjectIdReader(ctxt) != null);
558+
boolean useObjectId = (_valueDeserializer.getObjectIdReader(ctxt) != null);
567559
if (useObjectId) {
568560
referringAccumulator = new MapReferringAccumulator(_containerType.getContentType().getRawClass(), result);
569561
}
@@ -596,10 +588,8 @@ protected final Map<Object,Object> _readAndBindStringKeyMap(JsonParser p, Deseri
596588
continue;
597589
}
598590
value = _nullProvider.getNullValue(ctxt);
599-
} else if (typeDeser == null) {
600-
value = valueDes.deserialize(p, ctxt);
601591
} else {
602-
value = valueDes.deserializeWithType(p, ctxt, typeDeser);
592+
value = _deserializeNoNullChecks(p, ctxt);
603593
}
604594
if (useObjectId) {
605595
referringAccumulator.put(key, value);
@@ -628,9 +618,6 @@ public Map<Object,Object> _deserializeUsingCreator(JsonParser p, Deserialization
628618
// null -> no ObjectIdReader for Maps (yet?)
629619
PropertyValueBuffer buffer = creator.startBuilding(p, ctxt, null);
630620

631-
final ValueDeserializer<Object> valueDes = _valueDeserializer;
632-
final TypeDeserializer typeDeser = _valueTypeDeserializer;
633-
634621
String key;
635622
if (p.isExpectedStartObjectToken()) {
636623
key = p.nextName();
@@ -672,10 +659,8 @@ public Map<Object,Object> _deserializeUsingCreator(JsonParser p, Deserialization
672659
continue;
673660
}
674661
value = _nullProvider.getNullValue(ctxt);
675-
} else if (typeDeser == null) {
676-
value = valueDes.deserialize(p, ctxt);
677662
} else {
678-
value = valueDes.deserializeWithType(p, ctxt, typeDeser);
663+
value = _deserializeNoNullChecks(p, ctxt);
679664
}
680665
} catch (Exception e) {
681666
wrapAndThrow(ctxt, e, _containerType.getRawClass(), key);
@@ -702,7 +687,6 @@ public Map<Object,Object> _deserializeUsingCreator(JsonParser p, Deserialization
702687
protected final void _readAndUpdate(JsonParser p, DeserializationContext ctxt,
703688
Map<Object,Object> result) throws JacksonException
704689
{
705-
final KeyDeserializer keyDes = _keyDeserializer;
706690
final ValueDeserializer<Object> valueDes = _valueDeserializer;
707691
final TypeDeserializer typeDeser = _valueTypeDeserializer;
708692

@@ -724,7 +708,7 @@ protected final void _readAndUpdate(JsonParser p, DeserializationContext ctxt,
724708
}
725709

726710
for (; keyStr != null; keyStr = p.nextName()) {
727-
Object key = keyDes.deserializeKey(keyStr, ctxt);
711+
Object key = _keyDeserializer.deserializeKey(keyStr, ctxt);
728712
// And then the value...
729713
JsonToken t = p.nextToken();
730714
if ((_inclusionChecker != null) && _inclusionChecker.shouldIgnore(keyStr)) {
@@ -748,10 +732,8 @@ protected final void _readAndUpdate(JsonParser p, DeserializationContext ctxt,
748732
} else {
749733
value = valueDes.deserializeWithType(p, ctxt, typeDeser, old);
750734
}
751-
} else if (typeDeser == null) {
752-
value = valueDes.deserialize(p, ctxt);
753735
} else {
754-
value = valueDes.deserializeWithType(p, ctxt, typeDeser);
736+
value = _deserializeNoNullChecks(p, ctxt);
755737
}
756738
if (value != old) {
757739
result.put(key, value);
@@ -813,10 +795,8 @@ protected final void _readAndUpdateStringKeyMap(JsonParser p, DeserializationCon
813795
} else {
814796
value = valueDes.deserializeWithType(p, ctxt, typeDeser, old);
815797
}
816-
} else if (typeDeser == null) {
817-
value = valueDes.deserialize(p, ctxt);
818798
} else {
819-
value = valueDes.deserializeWithType(p, ctxt, typeDeser);
799+
value = _deserializeNoNullChecks(p, ctxt);
820800
}
821801
if (value != old) {
822802
result.put(key, value);
@@ -827,6 +807,22 @@ protected final void _readAndUpdateStringKeyMap(JsonParser p, DeserializationCon
827807
}
828808
}
829809

810+
/**
811+
* Deserialize the content of the map.
812+
* If _valueTypeDeserializer is null, use _valueDeserializer.deserialize; if non-null,
813+
* use _valueDeserializer.deserializeWithType to deserialize value.
814+
* This method only performs deserialization and does not consider _skipNullValues, _nullProvider, etc.
815+
* @since 2.19.2
816+
*/
817+
protected Object _deserializeNoNullChecks(JsonParser p, DeserializationContext ctxt)
818+
throws JacksonException
819+
{
820+
if (_valueTypeDeserializer == null) {
821+
return _valueDeserializer.deserialize(p, ctxt);
822+
}
823+
return _valueDeserializer.deserializeWithType(p, ctxt, _valueTypeDeserializer);
824+
}
825+
830826
/**
831827
* @since 2.14
832828
*/
@@ -869,11 +865,11 @@ private void handleUnresolvedReference(DeserializationContext ctxt,
869865

870866
private final static class MapReferringAccumulator {
871867
private final Class<?> _valueType;
872-
private Map<Object,Object> _result;
868+
private final Map<Object,Object> _result;
873869
/**
874870
* A list of {@link MapReferring} to maintain ordering.
875871
*/
876-
private List<MapReferring> _accumulator = new ArrayList<MapReferring>();
872+
private final List<MapReferring> _accumulator = new ArrayList<MapReferring>();
877873

878874
public MapReferringAccumulator(Class<?> valueType, Map<Object, Object> result) {
879875
_valueType = valueType;

0 commit comments

Comments
 (0)