diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index 055ce9ece6..5377415494 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -38,16 +38,12 @@ Project: jackson-databind #4788: `EnumFeature.WRITE_ENUMS_TO_LOWERCASE` overrides `@JsonProperty` values (reported by Mike M) (fix by Joo-Hyuk K) +#4790: Fix `@JsonAnySetter` issue with "setter" method (related to #4639) + (reported by @bsa01) + (fix by Joo-Hyuk K) 2.18.1 (28-Oct-2024) -#4741: When `Include.NON_DEFAULT` setting is used on POJO, empty values - are not included in json if default is `null` - (reported by @ragnhov) - (fix by Joo-Hyuk K) -#4749: Fixed a problem with `StdDelegatingSerializer#serializeWithType` looking up the serializer - with the wrong argument - (fix by wrongwrong) #4508: Deserialized JsonAnySetter field in Kotlin data class is null (reported by @MaximValeev) (fix by Joo-Hyuk K) @@ -59,6 +55,14 @@ Project: jackson-databind #4724: Deserialization behavior change with Records, `@JsonCreator` and `@JsonValue` between 2.17 and 2.18 (reported by Antti L) +#4727: Eclipse having issues due`module-info` class "lost" on 2.18.0 jars +#4741: When `Include.NON_DEFAULT` setting is used on POJO, empty values + are not included in json if default is `null` + (reported by @ragnhov) + (fix by Joo-Hyuk K) +#4749: Fixed a problem with `StdDelegatingSerializer#serializeWithType` looking up the serializer + with the wrong argument + (fix by wrongwrong) 2.18.0 (26-Sep-2024) diff --git a/src/main/java/tools/jackson/databind/deser/SettableAnyProperty.java b/src/main/java/tools/jackson/databind/deser/SettableAnyProperty.java index 24e6e6d9c1..7b7f1564b9 100644 --- a/src/main/java/tools/jackson/databind/deser/SettableAnyProperty.java +++ b/src/main/java/tools/jackson/databind/deser/SettableAnyProperty.java @@ -184,6 +184,13 @@ Object readResolve() { */ public boolean isFieldType() { return _setterIsField; } + /** + * Method called to check whether this property is method + * + * @return 2.18.2 + */ + public boolean isSetterType() { return _setter instanceof AnnotatedMethod; } + /** * Create an instance of value to pass through Creator parameter. * diff --git a/src/main/java/tools/jackson/databind/deser/bean/BeanDeserializer.java b/src/main/java/tools/jackson/databind/deser/bean/BeanDeserializer.java index 38201cc798..f4f237d1f5 100644 --- a/src/main/java/tools/jackson/databind/deser/bean/BeanDeserializer.java +++ b/src/main/java/tools/jackson/databind/deser/bean/BeanDeserializer.java @@ -654,7 +654,9 @@ protected Object _deserializeUsingPropertyBased(final JsonParser p, final Deseri if (_anySetter != null) { try { // [databind#4639] Since 2.18.1 AnySetter might not part of the creator, but just some field. - if (_anySetter.isFieldType()) { + if (_anySetter.isFieldType() || + // [databind#4639] 2.18.2: Also should account for setter type :-/ + _anySetter.isSetterType()) { buffer.bufferAnyProperty(_anySetter, propName, _anySetter.deserialize(p, ctxt)); } else { buffer.bufferAnyParameterProperty(_anySetter, propName, _anySetter.deserialize(p, ctxt)); diff --git a/src/test/java/tools/jackson/databind/deser/AnySetterFieldWithCreator4639Test.java b/src/test/java/tools/jackson/databind/deser/AnySetterFieldWithCreator4639Test.java index 13a8ffd88c..efcb1862f6 100644 --- a/src/test/java/tools/jackson/databind/deser/AnySetterFieldWithCreator4639Test.java +++ b/src/test/java/tools/jackson/databind/deser/AnySetterFieldWithCreator4639Test.java @@ -1,5 +1,6 @@ package tools.jackson.databind.deser; +import java.util.HashMap; import java.util.Map; import org.junit.jupiter.api.Test; @@ -8,6 +9,7 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import tools.jackson.databind.ObjectMapper; import tools.jackson.databind.testutil.DatabindTestUtil; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -31,13 +33,49 @@ public Bean(@JsonProperty("b") int b, @JsonProperty("d") int d) { } } + public static class SomeBean { + final int b; + final int d; + final Map any = new HashMap<>(); + + @JsonCreator + public SomeBean(@JsonProperty("b") int b, @JsonProperty("d") int d) { + this.b = b; + this.d = d; + } + + @JsonAnySetter + public void setAny(String name, Object value) { + any.put(name, value); + } + } + + private final ObjectMapper MAPPER = newJsonMapper(); + @Test public void testJsonAnySetter() throws Exception { String json = "{\"a\":1,\"b\":2,\"c\":3,\"d\":4,\"e\":5,\"f\":6}"; - Bean bean = newJsonMapper().readValue(json, Bean.class); + Bean bean = MAPPER.readValue(json, Bean.class); + assertEquals(2, bean.b); + assertEquals(4, bean.d); + + // failed with: + // org.opentest4j.AssertionFailedError: + // Expected :{b=2, c=3, e=5, f=6} + // Actual :{e=5, f=6} + assertEquals(mapOf("a", 1, "c", 3, "e", 5, "f", 6), bean.any); + } + + @Test + public void testJsonAnySetterWithField() + throws Exception + { + String json = "{\"a\":1,\"b\":2,\"c\":3,\"d\":4,\"e\":5,\"f\":6}"; + + SomeBean bean = MAPPER.readValue(json, SomeBean.class); assertEquals(2, bean.b); assertEquals(4, bean.d);