Skip to content

Commit 47e0736

Browse files
authored
Fix #4777: make 0-args factory method become "default Creator" as in 2.17 (#4799)
1 parent 76e571d commit 47e0736

File tree

5 files changed

+39
-30
lines changed

5 files changed

+39
-30
lines changed

release-notes/CREDITS-2.x

+4
Original file line numberDiff line numberDiff line change
@@ -1846,6 +1846,10 @@ wrongwrong (@k163377)
18461846
on the pre-converted value when _delegateSerializer was null
18471847
(2.18.1)
18481848

1849+
Bernd Ahlers (@bernd)
1850+
* Reported #4742: Deserialization with Builder, External type id, `@JsonCreator` failing
1851+
(2.18.2)
1852+
18491853
Mike Minicki (@martel)
18501854
* Reported #4788: `EnumFeature.WRITE_ENUMS_TO_LOWERCASE` overrides `@JsonProperty` values
18511855
(2.18.2)

release-notes/VERSION-2.x

+6-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ Project: jackson-databind
88

99
#4733: Wrong serialization of Type Ids for certain types of Enum values
1010
(reported by @nlisker)
11+
#4742: Deserialization with Builder, External type id, `@JsonCreator` failing
12+
(reported by Bernd A)
13+
#4777: `StdValueInstantiator.withArgsCreator` is now set for creators with
14+
no arguments
15+
(reported by @wrongwrong)
1116
#4783 Possibly wrong behavior of @JsonMerge
1217
(reported by @nlisker)
1318
(fix by Joo-Hyuk K)
@@ -40,7 +45,7 @@ Project: jackson-databind
4045
(fix by Joo-Hyuk K)
4146
#4749: Fixed a problem with `StdDelegatingSerializer#serializeWithType` looking up the serializer
4247
with the wrong argument
43-
(fix by wrongwrong)
48+
(fix by @wrongwrong)
4449

4550
2.18.0 (26-Sep-2024)
4651

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

+14-7
Original file line numberDiff line numberDiff line change
@@ -260,10 +260,16 @@ protected ValueInstantiator _constructDefaultValueInstantiator(DeserializationCo
260260
if (potentialCreators.hasPropertiesBased()) {
261261
PotentialCreator primaryPropsBased = potentialCreators.propertiesBased;
262262

263-
// Start by assigning the primary (and only) properties-based creator
264-
_addSelectedPropertiesBasedCreator(ctxt, beanDesc, creators,
265-
CreatorCandidate.construct(config.getAnnotationIntrospector(),
266-
primaryPropsBased.creator(), primaryPropsBased.propertyDefs()));
263+
// 12-Nov-2024, tatu: [databind#4777] We may have collected a 0-args Factory
264+
// method; and if so, may need to "pull it out" as default creator
265+
if (primaryPropsBased.paramCount() == 0) {
266+
creators.setDefaultCreator(primaryPropsBased.creator());
267+
} else {
268+
// Start by assigning the primary (and only) properties-based creator
269+
_addSelectedPropertiesBasedCreator(ctxt, beanDesc, creators,
270+
CreatorCandidate.construct(config.getAnnotationIntrospector(),
271+
primaryPropsBased.creator(), primaryPropsBased.propertyDefs()));
272+
}
267273
}
268274

269275
// Continue with explicitly annotated delegating Creators
@@ -283,9 +289,10 @@ protected ValueInstantiator _constructDefaultValueInstantiator(DeserializationCo
283289
// First things first: the "default constructor" (zero-arg
284290
// constructor; whether implicit or explicit) is NOT included
285291
// in list of constructors, so needs to be handled separately.
286-
AnnotatedConstructor defaultCtor = beanDesc.findDefaultConstructor();
287-
if (defaultCtor != null) {
288-
if (!creators.hasDefaultCreator() || _hasCreatorAnnotation(config, defaultCtor)) {
292+
// However, we may have added one for 0-args Factory method earlier, so:
293+
if (!creators.hasDefaultCreator()) {
294+
AnnotatedConstructor defaultCtor = beanDesc.findDefaultConstructor();
295+
if (defaultCtor != null) {
289296
creators.setDefaultCreator(defaultCtor);
290297
}
291298
}

src/test/java/com/fasterxml/jackson/databind/tofix/JacksonBuilderCreatorSubtype4742Test.java renamed to src/test/java/com/fasterxml/jackson/databind/deser/builder/BuilderCreatorSubtype4742Test.java

+6-11
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,21 @@
1-
package com.fasterxml.jackson.databind.tofix;
1+
package com.fasterxml.jackson.databind.deser.builder;
22

33
import java.util.List;
44

55
import org.junit.jupiter.api.Test;
66

7-
import com.fasterxml.jackson.annotation.JsonCreator;
8-
import com.fasterxml.jackson.annotation.JsonProperty;
9-
import com.fasterxml.jackson.annotation.JsonSubTypes;
10-
import com.fasterxml.jackson.annotation.JsonTypeInfo;
7+
import com.fasterxml.jackson.annotation.*;
8+
119
import com.fasterxml.jackson.databind.ObjectMapper;
1210
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
1311
import com.fasterxml.jackson.databind.testutil.DatabindTestUtil;
14-
import com.fasterxml.jackson.databind.testutil.failure.JacksonTestFailureExpected;
1512

1613
import static org.junit.jupiter.api.Assertions.assertEquals;
1714
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
1815

1916
// [databind#4742] Deserialization with Builder, External type id,
20-
// @JsonCreator not yet implemented
21-
public class JacksonBuilderCreatorSubtype4742Test
17+
// @JsonCreator failing
18+
public class BuilderCreatorSubtype4742Test
2219
extends DatabindTestUtil
2320
{
2421
public static class Animals {
@@ -110,9 +107,8 @@ public String toString() {
110107

111108
private final ObjectMapper MAPPER = newJsonMapper();
112109

113-
@JacksonTestFailureExpected
114110
@Test
115-
public void testDeser() throws Exception
111+
public void testDeser4742() throws Exception
116112
{
117113
final Animals animals = MAPPER.readValue(
118114
"{\n" +
@@ -125,6 +121,5 @@ public void testDeser() throws Exception
125121
assertEquals(2, animals.animals.size());
126122
assertInstanceOf(BirdProperties.class, animals.animals.get(0).properties);
127123
assertInstanceOf(MammalProperties.class, animals.animals.get(1).properties);
128-
129124
}
130125
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.fasterxml.jackson.databind.tofix;
1+
package com.fasterxml.jackson.databind.deser.creators;
22

33
import org.junit.jupiter.api.Test;
44

@@ -10,29 +10,28 @@
1010
import com.fasterxml.jackson.databind.json.JsonMapper;
1111
import com.fasterxml.jackson.databind.module.SimpleModule;
1212
import com.fasterxml.jackson.databind.testutil.DatabindTestUtil;
13-
import com.fasterxml.jackson.databind.testutil.failure.JacksonTestFailureExpected;
1413

1514
import static org.junit.jupiter.api.Assertions.assertNotNull;
1615

1716
public class JsonCreatorNoArgs4777Test extends DatabindTestUtil
1817
{
19-
static class Foo {
20-
private Foo() { }
18+
static class Foo4777 {
19+
Foo4777() { }
2120

2221
@JsonCreator
23-
static Foo create() {
24-
return new Foo();
22+
static Foo4777 create() {
23+
return new Foo4777();
2524
}
2625
}
2726

28-
static class Instantiators implements ValueInstantiators {
27+
static class Instantiators4777 implements ValueInstantiators {
2928
@Override
3029
public ValueInstantiator findValueInstantiator(
3130
DeserializationConfig config,
3231
BeanDescription beanDesc,
3332
ValueInstantiator defaultInstantiator
3433
) {
35-
if (beanDesc.getBeanClass() == Foo.class) {
34+
if (beanDesc.getBeanClass() == Foo4777.class) {
3635
AnnotatedWithParams dc = defaultInstantiator.getDefaultCreator();
3736
if (!(dc instanceof AnnotatedMethod)
3837
|| !dc.getName().equals("create")) {
@@ -47,18 +46,17 @@ public ValueInstantiator findValueInstantiator(
4746
// For [databind#4777]
4847
@SuppressWarnings("serial")
4948
@Test
50-
@JacksonTestFailureExpected
5149
public void testCreatorDetection4777() throws Exception {
5250
SimpleModule sm = new SimpleModule() {
5351
@Override
5452
public void setupModule(SetupContext context) {
5553
super.setupModule(context);
56-
context.addValueInstantiators(new Instantiators());
54+
context.addValueInstantiators(new Instantiators4777());
5755
}
5856
};
5957
ObjectMapper mapper = JsonMapper.builder().addModule(sm).build();
6058

61-
Foo result = mapper.readValue("{}", Foo.class);
59+
Foo4777 result = mapper.readValue("{}", Foo4777.class);
6260
assertNotNull(result);
6361
}
6462
}

0 commit comments

Comments
 (0)