Skip to content

Commit a79ce09

Browse files
authored
Add any-setter handling in PropertyValueBuffer post #562 (#4720)
1 parent 974eb40 commit a79ce09

File tree

3 files changed

+52
-7
lines changed

3 files changed

+52
-7
lines changed

release-notes/CREDITS-2.x

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1834,3 +1834,6 @@ Rikkarth (rikkarth@github)
18341834
* Contributed #4709: Add `JacksonCollectors` with `toArrayNode()` implementation
18351835
(2.18.0)
18361836

1837+
Maxim Valeev (@MaximValeev)
1838+
* Reported #4508: Deserialized JsonAnySetter field in Kotlin data class is null
1839+
(2.18.1)

release-notes/VERSION-2.x

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ Project: jackson-databind
44
=== Releases ===
55
------------------------------------------------------------------------
66

7+
2.18.1 (WIP-2024)
8+
9+
#4508: Deserialized JsonAnySetter field in Kotlin data class is null
10+
(reported by @MaximValeev)
11+
(fix by Joo-Hyuk K)
12+
713
2.18.0 (26-Sep-2024)
814

915
#562: Allow `@JsonAnySetter` to flow through Creators

src/main/java/com/fasterxml/jackson/databind/deser/impl/PropertyValueBuffer.java

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,24 @@ public PropertyValueBuffer(JsonParser p, DeserializationContext ctxt, int paramC
135135
*/
136136
public final boolean hasParameter(SettableBeanProperty prop)
137137
{
138+
final int ix = prop.getCreatorIndex();
139+
138140
if (_paramsSeenBig == null) {
139-
return ((_paramsSeen >> prop.getCreatorIndex()) & 1) == 1;
141+
if (((_paramsSeen >> ix) & 1) == 1) {
142+
return true;
143+
}
144+
} else {
145+
if (_paramsSeenBig.get(ix)) {
146+
return true;
147+
}
140148
}
141-
return _paramsSeenBig.get(prop.getCreatorIndex());
149+
// 28-Sep-2024 : [databind#4508] Support any-setter flowing through creator
150+
if (_anyParamSetter != null) {
151+
if (ix == _anyParamSetter.getParameterIndex()) {
152+
return true;
153+
}
154+
}
155+
return false;
142156
}
143157

144158
/**
@@ -160,6 +174,11 @@ public Object getParameter(SettableBeanProperty prop)
160174
} else {
161175
value = _creatorParameters[prop.getCreatorIndex()] = _findMissing(prop);
162176
}
177+
// 28-Sep-2024 : [databind#4508] Support any-setter flowing through creator
178+
if ((value == null) && (_anyParamSetter != null )
179+
&& (prop.getCreatorIndex() == _anyParamSetter.getParameterIndex())) {
180+
value = _createAndSetAnySetterValue();
181+
}
163182
if (value == null && _context.isEnabled(DeserializationFeature.FAIL_ON_NULL_CREATOR_PROPERTIES)) {
164183
return _context.reportInputMismatch(prop,
165184
"Null value for creator property '%s' (index %d); `DeserializationFeature.FAIL_ON_NULL_CREATOR_PROPERTIES` enabled",
@@ -198,11 +217,7 @@ public Object[] getParameters(SettableBeanProperty[] props)
198217
}
199218
// [databind#562] since 2.18 : Respect @JsonAnySetter in @JsonCreator
200219
if (_anyParamSetter != null) {
201-
Object anySetterParameterObject = _anyParamSetter.createParameterObject();
202-
for (PropertyValue pv = _anyParamBuffered; pv != null; pv = pv.next) {
203-
pv.setValue(anySetterParameterObject);
204-
}
205-
_creatorParameters[_anyParamSetter.getParameterIndex()] = anySetterParameterObject;
220+
_creatorParameters[_anyParamSetter.getParameterIndex()] = _createAndSetAnySetterValue();
206221
}
207222
if (_context.isEnabled(DeserializationFeature.FAIL_ON_NULL_CREATOR_PROPERTIES)) {
208223
for (int ix = 0; ix < props.length; ++ix) {
@@ -217,6 +232,27 @@ public Object[] getParameters(SettableBeanProperty[] props)
217232
return _creatorParameters;
218233
}
219234

235+
/**
236+
* Helper method called to create and set any values buffered for "any setter"
237+
*/
238+
private Object _createAndSetAnySetterValue() throws JsonMappingException
239+
{
240+
Object anySetterParameterObject = _anyParamSetter.createParameterObject();
241+
for (PropertyValue pv = _anyParamBuffered; pv != null; pv = pv.next) {
242+
try {
243+
pv.setValue(anySetterParameterObject);
244+
245+
// Since one of callers only exposes JsonMappingException, but pv.setValue()
246+
// nominally leaks IOException, need to do this unfortunate conversion
247+
} catch (JsonMappingException e) {
248+
throw e;
249+
} catch (IOException e) {
250+
throw JsonMappingException.fromUnexpectedIOE(e);
251+
}
252+
}
253+
return anySetterParameterObject;
254+
}
255+
220256
protected Object _findMissing(SettableBeanProperty prop) throws JsonMappingException
221257
{
222258
// 08-Jun-2024: [databind#562] AnySetters are bit special

0 commit comments

Comments
 (0)