Skip to content

Commit

Permalink
Fix #4602: handling of Array-delegating Creator (#4609)
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder authored Jul 3, 2024
1 parent 8a42895 commit fd80718
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 6 deletions.
5 changes: 5 additions & 0 deletions release-notes/CREDITS-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -1812,3 +1812,8 @@ Alexandre Jacob (ajacob@github)
* Reported #4545: Unexpected deserialization behavior with `@JsonCreator`,
`@JsonProperty` and javac `-parameters`
(2.18.0)
Eduard Gomoliako (Gems@github)
* Reported #4602: Possible wrong use of _arrayDelegateDeserializer in
BeanDeserializerBase::deserializeFromObjectUsingNonDefault()
(2.18.0)
3 changes: 3 additions & 0 deletions release-notes/VERSION-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ Project: jackson-databind
#4570: Deprecate `ObjectMapper.canDeserialize()`/`ObjectMapper.canSerialize()`
#4580: Add `MapperFeature.SORT_CREATOR_PROPERTIES_BY_DECLARATION_ORDER` to use
Creator properties' declaration order for sorting
#4602: Possible wrong use of _arrayDelegateDeserializer in
BeanDeserializerBase::deserializeFromObjectUsingNonDefault()
(reported by Eduard G)

2.17.2 (not yet released)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1482,7 +1482,9 @@ protected Object deserializeFromObjectId(JsonParser p, DeserializationContext ct
protected Object deserializeFromObjectUsingNonDefault(JsonParser p,
DeserializationContext ctxt) throws IOException
{
final JsonDeserializer<Object> delegateDeser = _delegateDeserializer();
// 02-Jul-2024, tatu: [databind#4602] Need to tweak regular and "array" delegating
// Creator handling
final JsonDeserializer<Object> delegateDeser = _delegateDeserializer(p);
if (delegateDeser != null) {
final Object bean = _valueInstantiator.createUsingDelegate(ctxt,
delegateDeser.deserialize(p, ctxt));
Expand All @@ -1505,7 +1507,7 @@ protected Object deserializeFromObjectUsingNonDefault(JsonParser p,
// 01-May-2022, tatu: [databind#3417] special handling for (Graal) native images
if (NativeImageUtil.needsReflectionConfiguration(raw)) {
return ctxt.handleMissingInstantiator(raw, null, p,
"cannot deserialize from Object value (no delegate- or property-based Creator): this appears to be a native image, in which case you may need to configure reflection for the class that is to be deserialized");
"cannot deserialize from Object value (no delegate- or property-based Creator): this appears to be a native image, in which case you may need to configure reflection for the class that is to be deserialized");
}
return ctxt.handleMissingInstantiator(raw, getValueInstantiator(), p,
"cannot deserialize from Object value (no delegate- or property-based Creator)");
Expand Down Expand Up @@ -1710,6 +1712,30 @@ protected final JsonDeserializer<Object> _delegateDeserializer() {
return deser;
}

/**
* Alternate to {@link #_delegateDeserializer()} which will only consider
* {@code _arrayDelegateDeserializer} if given {@link JsonParser} points to
* {@link JsonToken#START_ARRAY} token.
*
* @since 2.18
*/
protected final JsonDeserializer<Object> _delegateDeserializer(JsonParser p) {
if (_delegateDeserializer == null) {
// Note! Will not call `JsonParser.isExpectedArrayToken()` as that could
// "transform" `JsonToken.START_OBJECT` into `JsonToken.START_ARRAY` and
// here there is no strong expectation of Array value
if (_arrayDelegateDeserializer != null) {
// Alas, need bit elaborate logic: either JSON Array, OR no
// Properties-based Creator
if (p.hasToken(JsonToken.START_ARRAY)
|| (_propertyBasedCreator == null)) {
return _arrayDelegateDeserializer;
}
}
}
return _delegateDeserializer;
}

/*
/**********************************************************
/* Overridable helper methods
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.fasterxml.jackson.failing;
package com.fasterxml.jackson.databind.deser.creators;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@

public class SingleValueAsArrayTest extends DatabindTestUtil
{
private static final String JSON = "[{\"message\":\"messageHere\"}]";

static class Bean1421A
{
List<Messages> bs = Collections.emptyList();
Expand Down Expand Up @@ -77,8 +75,10 @@ public Bean1421B(T value) {
@Test
public void testSuccessfulDeserializationOfObjectWithChainedArrayCreators() throws IOException
{
Bean1421A result = MAPPER.readValue(JSON, Bean1421A.class);
Bean1421A result = MAPPER.readValue("[{\"message\":\"messageHere\"}]", Bean1421A.class);
assertNotNull(result);
assertNotNull(result.bs);
assertEquals(1, result.bs.size());
}

@Test
Expand Down

0 comments on commit fd80718

Please sign in to comment.