Skip to content

Commit d0cfb64

Browse files
committed
Fix #1421
1 parent 1aeb525 commit d0cfb64

File tree

3 files changed

+50
-42
lines changed

3 files changed

+50
-42
lines changed

release-notes/VERSION

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Project: jackson-databind
77
2.8.5 (not yet released)
88

99
#1417: Further issues with `@JsonInclude` with `NON_DEFAULT`
10+
#1421: ACCEPT_SINGLE_VALUE_AS_ARRAY partially broken in 2.7.x, 2.8.x
1011
#1429: `StdKeyDeserializer` can erroneously use a static factory method
1112
with more than one argument
1213
#1432: Off by 1 bug in PropertyValueBuffer

src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java

+47-40
Original file line numberDiff line numberDiff line change
@@ -1189,9 +1189,10 @@ protected Object deserializeFromObjectId(JsonParser p, DeserializationContext ct
11891189
protected Object deserializeFromObjectUsingNonDefault(JsonParser p,
11901190
DeserializationContext ctxt) throws IOException
11911191
{
1192-
if (_delegateDeserializer != null) {
1192+
final JsonDeserializer<Object> delegateDeser = _delegateDeserializer();
1193+
if (delegateDeser != null) {
11931194
return _valueInstantiator.createUsingDelegate(ctxt,
1194-
_delegateDeserializer.deserialize(p, ctxt));
1195+
delegateDeser.deserialize(p, ctxt));
11951196
}
11961197
if (_propertyBasedCreator != null) {
11971198
return _deserializeUsingPropertyBased(p, ctxt);
@@ -1210,19 +1211,20 @@ protected abstract Object _deserializeUsingPropertyBased(final JsonParser p,
12101211
throws IOException, JsonProcessingException;
12111212

12121213
@SuppressWarnings("incomplete-switch")
1213-
public Object deserializeFromNumber(JsonParser p, DeserializationContext ctxt) throws IOException
1214+
public Object deserializeFromNumber(JsonParser p, DeserializationContext ctxt)
1215+
throws IOException
12141216
{
12151217
// First things first: id Object Id is used, most likely that's it
12161218
if (_objectIdReader != null) {
12171219
return deserializeFromObjectId(p, ctxt);
12181220
}
1219-
1221+
final JsonDeserializer<Object> delegateDeser = _delegateDeserializer();
12201222
switch (p.getNumberType()) {
12211223
case INT:
1222-
if (_delegateDeserializer != null) {
1224+
if (delegateDeser != null) {
12231225
if (!_valueInstantiator.canCreateFromInt()) {
12241226
Object bean = _valueInstantiator.createUsingDelegate(ctxt,
1225-
_delegateDeserializer.deserialize(p, ctxt));
1227+
delegateDeser.deserialize(p, ctxt));
12261228
if (_injectables != null) {
12271229
injectValues(ctxt, bean);
12281230
}
@@ -1231,10 +1233,10 @@ public Object deserializeFromNumber(JsonParser p, DeserializationContext ctxt) t
12311233
}
12321234
return _valueInstantiator.createFromInt(ctxt, p.getIntValue());
12331235
case LONG:
1234-
if (_delegateDeserializer != null) {
1236+
if (delegateDeser != null) {
12351237
if (!_valueInstantiator.canCreateFromInt()) {
12361238
Object bean = _valueInstantiator.createUsingDelegate(ctxt,
1237-
_delegateDeserializer.deserialize(p, ctxt));
1239+
delegateDeser.deserialize(p, ctxt));
12381240
if (_injectables != null) {
12391241
injectValues(ctxt, bean);
12401242
}
@@ -1244,9 +1246,9 @@ public Object deserializeFromNumber(JsonParser p, DeserializationContext ctxt) t
12441246
return _valueInstantiator.createFromLong(ctxt, p.getLongValue());
12451247
}
12461248
// actually, could also be BigInteger, so:
1247-
if (_delegateDeserializer != null) {
1249+
if (delegateDeser != null) {
12481250
Object bean = _valueInstantiator.createUsingDelegate(ctxt,
1249-
_delegateDeserializer.deserialize(p, ctxt));
1251+
delegateDeser.deserialize(p, ctxt));
12501252
if (_injectables != null) {
12511253
injectValues(ctxt, bean);
12521254
}
@@ -1263,13 +1265,14 @@ public Object deserializeFromString(JsonParser p, DeserializationContext ctxt) t
12631265
if (_objectIdReader != null) {
12641266
return deserializeFromObjectId(p, ctxt);
12651267
}
1266-
12671268
/* Bit complicated if we have delegating creator; may need to use it,
12681269
* or might not...
12691270
*/
1270-
if (_delegateDeserializer != null) {
1271+
JsonDeserializer<Object> delegateDeser = _delegateDeserializer();
1272+
if (delegateDeser != null) {
12711273
if (!_valueInstantiator.canCreateFromString()) {
1272-
Object bean = _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(p, ctxt));
1274+
Object bean = _valueInstantiator.createUsingDelegate(ctxt,
1275+
delegateDeser.deserialize(p, ctxt));
12731276
if (_injectables != null) {
12741277
injectValues(ctxt, bean);
12751278
}
@@ -1288,9 +1291,11 @@ public Object deserializeFromDouble(JsonParser p, DeserializationContext ctxt) t
12881291
NumberType t = p.getNumberType();
12891292
// no separate methods for taking float...
12901293
if ((t == NumberType.DOUBLE) || (t == NumberType.FLOAT)) {
1291-
if (_delegateDeserializer != null) {
1294+
JsonDeserializer<Object> delegateDeser = _delegateDeserializer();
1295+
if (delegateDeser != null) {
12921296
if (!_valueInstantiator.canCreateFromDouble()) {
1293-
Object bean = _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(p, ctxt));
1297+
Object bean = _valueInstantiator.createUsingDelegate(ctxt,
1298+
delegateDeser.deserialize(p, ctxt));
12941299
if (_injectables != null) {
12951300
injectValues(ctxt, bean);
12961301
}
@@ -1300,8 +1305,10 @@ public Object deserializeFromDouble(JsonParser p, DeserializationContext ctxt) t
13001305
return _valueInstantiator.createFromDouble(ctxt, p.getDoubleValue());
13011306
}
13021307
// actually, could also be BigDecimal, so:
1303-
if (_delegateDeserializer != null) {
1304-
return _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(p, ctxt));
1308+
JsonDeserializer<Object> delegateDeser = _delegateDeserializer();
1309+
if (delegateDeser != null) {
1310+
return _valueInstantiator.createUsingDelegate(ctxt,
1311+
delegateDeser.deserialize(p, ctxt));
13051312
}
13061313
return ctxt.handleMissingInstantiator(handledType(), p,
13071314
"no suitable creator method found to deserialize from Number value (%s)",
@@ -1313,9 +1320,11 @@ public Object deserializeFromDouble(JsonParser p, DeserializationContext ctxt) t
13131320
*/
13141321
public Object deserializeFromBoolean(JsonParser p, DeserializationContext ctxt) throws IOException
13151322
{
1316-
if (_delegateDeserializer != null) {
1323+
JsonDeserializer<Object> delegateDeser = _delegateDeserializer();
1324+
if (delegateDeser != null) {
13171325
if (!_valueInstantiator.canCreateFromBoolean()) {
1318-
Object bean = _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(p, ctxt));
1326+
Object bean = _valueInstantiator.createUsingDelegate(ctxt,
1327+
delegateDeser.deserialize(p, ctxt));
13191328
if (_injectables != null) {
13201329
injectValues(ctxt, bean);
13211330
}
@@ -1328,29 +1337,16 @@ public Object deserializeFromBoolean(JsonParser p, DeserializationContext ctxt)
13281337

13291338
public Object deserializeFromArray(JsonParser p, DeserializationContext ctxt) throws IOException
13301339
{
1331-
if (_arrayDelegateDeserializer != null) {
1332-
try {
1333-
Object bean = _valueInstantiator.createUsingArrayDelegate(ctxt, _arrayDelegateDeserializer.deserialize(p, ctxt));
1334-
if (_injectables != null) {
1335-
injectValues(ctxt, bean);
1336-
}
1337-
return bean;
1338-
} catch (Exception e) {
1339-
return wrapInstantiationProblem(e, ctxt);
1340-
}
1341-
}
1340+
// note: can not call `_delegateDeserializer()` since order reversed here:
1341+
JsonDeserializer<Object> delegateDeser = _arrayDelegateDeserializer;
13421342
// fallback to non-array delegate
1343-
if (_delegateDeserializer != null) {
1344-
try {
1345-
Object bean = _valueInstantiator.createUsingArrayDelegate(ctxt, _delegateDeserializer.deserialize(p, ctxt));
1346-
if (_injectables != null) {
1347-
injectValues(ctxt, bean);
1348-
}
1349-
return bean;
1350-
} catch (Exception e) {
1351-
wrapInstantiationProblem(e, ctxt);
1352-
return null;
1343+
if ((delegateDeser != null) || ((delegateDeser = _delegateDeserializer) != null)) {
1344+
Object bean = _valueInstantiator.createUsingArrayDelegate(ctxt,
1345+
delegateDeser.deserialize(p, ctxt));
1346+
if (_injectables != null) {
1347+
injectValues(ctxt, bean);
13531348
}
1349+
return bean;
13541350
}
13551351
if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
13561352
JsonToken t = p.nextToken();
@@ -1388,6 +1384,17 @@ public Object deserializeFromEmbedded(JsonParser p, DeserializationContext ctxt)
13881384
return p.getEmbeddedObject();
13891385
}
13901386

1387+
/**
1388+
* @since 2.9
1389+
*/
1390+
private final JsonDeserializer<Object> _delegateDeserializer() {
1391+
JsonDeserializer<Object> deser = _delegateDeserializer;
1392+
if (deser == null) {
1393+
deser = _arrayDelegateDeserializer;
1394+
}
1395+
return deser;
1396+
}
1397+
13911398
/*
13921399
/**********************************************************
13931400
/* Overridable helper methods

src/test/java/com/fasterxml/jackson/failing/SingleValueAsArray1421Test.java renamed to src/test/java/com/fasterxml/jackson/databind/struct/SingleValueAsArrayTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.fasterxml.jackson.failing;
1+
package com.fasterxml.jackson.databind.struct;
22

33
import java.io.IOException;
44
import java.util.ArrayList;
@@ -12,7 +12,7 @@
1212

1313
import com.fasterxml.jackson.databind.*;
1414

15-
public class SingleValueAsArray1421Test extends BaseMapTest
15+
public class SingleValueAsArrayTest extends BaseMapTest
1616
{
1717
private static final String JSON = "[{\"message\":\"messageHere\"}]";
1818

0 commit comments

Comments
 (0)