From a996e3d7e0368d550ecebf417317d887a23df209 Mon Sep 17 00:00:00 2001 From: Sandeep gaur Date: Sun, 29 Sep 2024 19:19:26 +0530 Subject: [PATCH 1/7] Fixed issues 4697 and 2461 --- .../fasterxml/jackson/databind/util/README.md | 3 + .../databind/ser/BeanPropertyWriter.java | 61 +++++++++++-------- ...ppedInconsistentSerialization4697Test.java | 22 ++++++- .../tofix/UnwrappedCaching2461Test.java | 1 - 4 files changed, 60 insertions(+), 27 deletions(-) create mode 100644 out/production/jackson-databind/com/fasterxml/jackson/databind/util/README.md diff --git a/out/production/jackson-databind/com/fasterxml/jackson/databind/util/README.md b/out/production/jackson-databind/com/fasterxml/jackson/databind/util/README.md new file mode 100644 index 0000000000..0ea12d2882 --- /dev/null +++ b/out/production/jackson-databind/com/fasterxml/jackson/databind/util/README.md @@ -0,0 +1,3 @@ +Place where formerly used code is moved if it seems possible (or perhaps even likely) it might +be reused at some point. Or, for some experimental code that isn't yet used. + diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java b/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java index 812c239032..241d7d05fd 100644 --- a/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java +++ b/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java @@ -24,6 +24,8 @@ import com.fasterxml.jackson.databind.util.ClassUtil; import com.fasterxml.jackson.databind.util.NameTransformer; +import static com.fasterxml.jackson.databind.ser.impl.PropertySerializerMap.emptyForProperties; + /** * Base bean property handler class, which implements common parts of * reflection-based functionality for accessing a property value and serializing @@ -36,7 +38,7 @@ @JacksonStdImpl // since 2.6. NOTE: sub-classes typically are not public class BeanPropertyWriter extends PropertyWriter // which extends - // `ConcreteBeanPropertyBase` + // `ConcreteBeanPropertyBase` implements java.io.Serializable // since 2.6 { // As of 2.7 @@ -207,11 +209,11 @@ public class BeanPropertyWriter extends PropertyWriter // which extends */ @SuppressWarnings("unchecked") public BeanPropertyWriter(BeanPropertyDefinition propDef, - AnnotatedMember member, Annotations contextAnnotations, - JavaType declaredType, - JsonSerializer ser, TypeSerializer typeSer, JavaType serType, - boolean suppressNulls, Object suppressableValue, - Class[] includeInViews) + AnnotatedMember member, Annotations contextAnnotations, + JavaType declaredType, + JsonSerializer ser, TypeSerializer typeSer, JavaType serType, + boolean suppressNulls, Object suppressableValue, + Class[] includeInViews) { super(propDef); _member = member; @@ -222,8 +224,7 @@ public BeanPropertyWriter(BeanPropertyDefinition propDef, _declaredType = declaredType; _serializer = (JsonSerializer) ser; - _dynamicSerializers = (ser == null) ? PropertySerializerMap - .emptyForProperties() : null; + _dynamicSerializers = (ser == null) ? emptyForProperties() : null; _typeSerializer = typeSer; _cfgSerializationType = serType; @@ -249,10 +250,10 @@ public BeanPropertyWriter(BeanPropertyDefinition propDef, @Deprecated // Since 2.9 public BeanPropertyWriter(BeanPropertyDefinition propDef, - AnnotatedMember member, Annotations contextAnnotations, - JavaType declaredType, - JsonSerializer ser, TypeSerializer typeSer, JavaType serType, - boolean suppressNulls, Object suppressableValue) + AnnotatedMember member, Annotations contextAnnotations, + JavaType declaredType, + JsonSerializer ser, TypeSerializer typeSer, JavaType serType, + boolean suppressNulls, Object suppressableValue) { this(propDef, member, contextAnnotations, declaredType, ser, typeSer, serType, suppressNulls, suppressableValue, @@ -325,7 +326,13 @@ protected BeanPropertyWriter(BeanPropertyWriter base, PropertyName name) { base._internalSettings); } _cfgSerializationType = base._cfgSerializationType; - _dynamicSerializers = base._dynamicSerializers; + //Need to clean deserializer in case of nested unwrapping bean properties + if(base instanceof UnwrappingBeanPropertyWriter) { + _dynamicSerializers = + emptyForProperties(); + } else { + _dynamicSerializers = base._dynamicSerializers; + } _suppressNulls = base._suppressNulls; _suppressableValue = base._suppressableValue; _includeInViews = base._includeInViews; @@ -350,7 +357,13 @@ protected BeanPropertyWriter(BeanPropertyWriter base, SerializedString name) { base._internalSettings); } _cfgSerializationType = base._cfgSerializationType; - _dynamicSerializers = base._dynamicSerializers; + //Need to clean deserializer in case of nested unwrapping bean properties + if(base instanceof UnwrappingBeanPropertyWriter) { + _dynamicSerializers = + emptyForProperties(); + } else { + _dynamicSerializers = base._dynamicSerializers; + } _suppressNulls = base._suppressNulls; _suppressableValue = base._suppressableValue; _includeInViews = base._includeInViews; @@ -459,7 +472,7 @@ Object readResolve() { _field = null; } if (_serializer == null) { - _dynamicSerializers = PropertySerializerMap.emptyForProperties(); + _dynamicSerializers = emptyForProperties(); } return this; } @@ -512,7 +525,7 @@ public AnnotatedMember getMember() { // @since 2.3 -- needed so it can be overridden by unwrapping writer protected void _depositSchemaProperty(ObjectNode propertiesNode, - JsonNode schemaNode) { + JsonNode schemaNode) { propertiesNode.set(getName(), schemaNode); } @@ -682,7 +695,7 @@ public Class[] getViews() { */ @Override public void serializeAsField(Object bean, JsonGenerator gen, - SerializerProvider prov) throws Exception { + SerializerProvider prov) throws Exception { // inlined 'get()' final Object value = (_accessorMethod == null) ? _field.get(bean) : _accessorMethod.invoke(bean, (Object[]) null); @@ -744,7 +757,7 @@ public void serializeAsField(Object bean, JsonGenerator gen, */ @Override public void serializeAsOmittedField(Object bean, JsonGenerator gen, - SerializerProvider prov) throws Exception { + SerializerProvider prov) throws Exception { if (!gen.canOmitFields()) { gen.writeOmittedField(_name.getValue()); } @@ -759,7 +772,7 @@ public void serializeAsOmittedField(Object bean, JsonGenerator gen, */ @Override public void serializeAsElement(Object bean, JsonGenerator gen, - SerializerProvider prov) throws Exception { + SerializerProvider prov) throws Exception { // inlined 'get()' final Object value = (_accessorMethod == null) ? _field.get(bean) : _accessorMethod.invoke(bean, (Object[]) null); @@ -785,7 +798,7 @@ public void serializeAsElement(Object bean, JsonGenerator gen, if (_suppressableValue != null) { if (MARKER_FOR_EMPTY == _suppressableValue) { if (ser.isEmpty(prov, value)) { // can NOT suppress entries in - // tabular output + // tabular output serializeAsPlaceholder(bean, gen, prov); return; } @@ -818,7 +831,7 @@ public void serializeAsElement(Object bean, JsonGenerator gen, */ @Override public void serializeAsPlaceholder(Object bean, JsonGenerator gen, - SerializerProvider prov) throws Exception { + SerializerProvider prov) throws Exception { if (_nullSerializer != null) { _nullSerializer.serialize(null, gen, prov); } else { @@ -835,7 +848,7 @@ public void serializeAsPlaceholder(Object bean, JsonGenerator gen, // Also part of BeanProperty implementation @Override public void depositSchemaProperty(JsonObjectFormatVisitor v, - SerializerProvider provider) throws JsonMappingException { + SerializerProvider provider) throws JsonMappingException { if (v != null) { if (isRequired()) { v.property(this); @@ -861,7 +874,7 @@ public void depositSchemaProperty(JsonObjectFormatVisitor v, @Override @Deprecated public void depositSchemaProperty(ObjectNode propertiesNode, - SerializerProvider provider) throws JsonMappingException { + SerializerProvider provider) throws JsonMappingException { JavaType propType = getSerializationType(); // 03-Dec-2010, tatu: SchemaAware REALLY should use JavaType, but alas // it doesn't... @@ -935,7 +948,7 @@ public final Object get(Object bean) throws Exception { * is no way handle it */ protected boolean _handleSelfReference(Object bean, JsonGenerator gen, - SerializerProvider prov, JsonSerializer ser) + SerializerProvider prov, JsonSerializer ser) throws IOException { if (!ser.usesObjectId()) { diff --git a/src/test/java/com/fasterxml/jackson/databind/tofix/JsonUnwrappedInconsistentSerialization4697Test.java b/src/test/java/com/fasterxml/jackson/databind/tofix/JsonUnwrappedInconsistentSerialization4697Test.java index f2e6057f64..565487e89d 100644 --- a/src/test/java/com/fasterxml/jackson/databind/tofix/JsonUnwrappedInconsistentSerialization4697Test.java +++ b/src/test/java/com/fasterxml/jackson/databind/tofix/JsonUnwrappedInconsistentSerialization4697Test.java @@ -35,13 +35,16 @@ public Third() { } } + public static class AnotherFirst { + public Third thrid = new Third(); + } + public static class Common { public String a; public String b; public Common() {} } - @JacksonTestFailureExpected @Test public void testInconsistentSer() throws Exception { First first = new First(); @@ -51,8 +54,23 @@ public void testInconsistentSer() throws Exception { ObjectMapper secondMapper = newJsonMapper(); firstMapper.writeValueAsString(first); + firstMapper.writeValueAsString(second); + assertEquals( + firstMapper.writeValueAsString(second), + secondMapper.writeValueAsString(second)); + } + @Test + public void testInconsistentSer1() throws Exception { + AnotherFirst first = new AnotherFirst(); + Second second = new Second(); + + ObjectMapper firstMapper = newJsonMapper(); + ObjectMapper secondMapper = newJsonMapper(); + + firstMapper.writeValueAsString(first); + firstMapper.writeValueAsString(second); assertEquals( firstMapper.writeValueAsString(second), secondMapper.writeValueAsString(second)); } -} +} \ No newline at end of file diff --git a/src/test/java/com/fasterxml/jackson/databind/tofix/UnwrappedCaching2461Test.java b/src/test/java/com/fasterxml/jackson/databind/tofix/UnwrappedCaching2461Test.java index dc3d867be9..2728b3a0dd 100644 --- a/src/test/java/com/fasterxml/jackson/databind/tofix/UnwrappedCaching2461Test.java +++ b/src/test/java/com/fasterxml/jackson/databind/tofix/UnwrappedCaching2461Test.java @@ -39,7 +39,6 @@ static class OuterContainer { } // [databind#2461] - @JacksonTestFailureExpected @Test void unwrappedCaching() throws Exception { final InnerContainer inner = new InnerContainer(new Base("12345")); From 0a304a15d553ff23a94de819bfc1b16eaabc0911 Mon Sep 17 00:00:00 2001 From: Sandeep gaur Date: Sun, 29 Sep 2024 19:46:33 +0530 Subject: [PATCH 2/7] removed unwanted changes pushed in last commit --- .../com/fasterxml/jackson/databind/util/README.md | 3 --- .../fasterxml/jackson/databind/ser/BeanPropertyWriter.java | 7 +++---- 2 files changed, 3 insertions(+), 7 deletions(-) delete mode 100644 out/production/jackson-databind/com/fasterxml/jackson/databind/util/README.md diff --git a/out/production/jackson-databind/com/fasterxml/jackson/databind/util/README.md b/out/production/jackson-databind/com/fasterxml/jackson/databind/util/README.md deleted file mode 100644 index 0ea12d2882..0000000000 --- a/out/production/jackson-databind/com/fasterxml/jackson/databind/util/README.md +++ /dev/null @@ -1,3 +0,0 @@ -Place where formerly used code is moved if it seems possible (or perhaps even likely) it might -be reused at some point. Or, for some experimental code that isn't yet used. - diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java b/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java index 241d7d05fd..17a135a003 100644 --- a/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java +++ b/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java @@ -224,7 +224,8 @@ public BeanPropertyWriter(BeanPropertyDefinition propDef, _declaredType = declaredType; _serializer = (JsonSerializer) ser; - _dynamicSerializers = (ser == null) ? emptyForProperties() : null; + _dynamicSerializers = (ser == null) ? PropertySerializerMap + .emptyForProperties() : null; _typeSerializer = typeSer; _cfgSerializationType = serType; @@ -326,7 +327,6 @@ protected BeanPropertyWriter(BeanPropertyWriter base, PropertyName name) { base._internalSettings); } _cfgSerializationType = base._cfgSerializationType; - //Need to clean deserializer in case of nested unwrapping bean properties if(base instanceof UnwrappingBeanPropertyWriter) { _dynamicSerializers = emptyForProperties(); @@ -357,7 +357,6 @@ protected BeanPropertyWriter(BeanPropertyWriter base, SerializedString name) { base._internalSettings); } _cfgSerializationType = base._cfgSerializationType; - //Need to clean deserializer in case of nested unwrapping bean properties if(base instanceof UnwrappingBeanPropertyWriter) { _dynamicSerializers = emptyForProperties(); @@ -472,7 +471,7 @@ Object readResolve() { _field = null; } if (_serializer == null) { - _dynamicSerializers = emptyForProperties(); + _dynamicSerializers = PropertySerializerMap.emptyForProperties(); } return this; } From 1d24c264dc06a3f629f4bd161cb47c2512344e3d Mon Sep 17 00:00:00 2001 From: Sandeep gaur Date: Sun, 29 Sep 2024 19:53:36 +0530 Subject: [PATCH 3/7] removed unwanted changes pushed in last commit --- .../databind/ser/BeanPropertyWriter.java | 46 +++++++++---------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java b/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java index 17a135a003..21ad497780 100644 --- a/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java +++ b/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java @@ -38,7 +38,7 @@ @JacksonStdImpl // since 2.6. NOTE: sub-classes typically are not public class BeanPropertyWriter extends PropertyWriter // which extends - // `ConcreteBeanPropertyBase` + // `ConcreteBeanPropertyBase` implements java.io.Serializable // since 2.6 { // As of 2.7 @@ -209,11 +209,11 @@ public class BeanPropertyWriter extends PropertyWriter // which extends */ @SuppressWarnings("unchecked") public BeanPropertyWriter(BeanPropertyDefinition propDef, - AnnotatedMember member, Annotations contextAnnotations, - JavaType declaredType, - JsonSerializer ser, TypeSerializer typeSer, JavaType serType, - boolean suppressNulls, Object suppressableValue, - Class[] includeInViews) + AnnotatedMember member, Annotations contextAnnotations, + JavaType declaredType, + JsonSerializer ser, TypeSerializer typeSer, JavaType serType, + boolean suppressNulls, Object suppressableValue, + Class[] includeInViews) { super(propDef); _member = member; @@ -224,8 +224,7 @@ public BeanPropertyWriter(BeanPropertyDefinition propDef, _declaredType = declaredType; _serializer = (JsonSerializer) ser; - _dynamicSerializers = (ser == null) ? PropertySerializerMap - .emptyForProperties() : null; + _dynamicSerializers = (ser == null) ? emptyForProperties() : null; _typeSerializer = typeSer; _cfgSerializationType = serType; @@ -251,10 +250,10 @@ public BeanPropertyWriter(BeanPropertyDefinition propDef, @Deprecated // Since 2.9 public BeanPropertyWriter(BeanPropertyDefinition propDef, - AnnotatedMember member, Annotations contextAnnotations, - JavaType declaredType, - JsonSerializer ser, TypeSerializer typeSer, JavaType serType, - boolean suppressNulls, Object suppressableValue) + AnnotatedMember member, Annotations contextAnnotations, + JavaType declaredType, + JsonSerializer ser, TypeSerializer typeSer, JavaType serType, + boolean suppressNulls, Object suppressableValue) { this(propDef, member, contextAnnotations, declaredType, ser, typeSer, serType, suppressNulls, suppressableValue, @@ -363,7 +362,7 @@ protected BeanPropertyWriter(BeanPropertyWriter base, SerializedString name) { } else { _dynamicSerializers = base._dynamicSerializers; } - _suppressNulls = base._suppressNulls; + _suppressNulls = base._suppressNulls; _suppressableValue = base._suppressableValue; _includeInViews = base._includeInViews; _typeSerializer = base._typeSerializer; @@ -471,7 +470,7 @@ Object readResolve() { _field = null; } if (_serializer == null) { - _dynamicSerializers = PropertySerializerMap.emptyForProperties(); + _dynamicSerializers = emptyForProperties(); } return this; } @@ -524,7 +523,7 @@ public AnnotatedMember getMember() { // @since 2.3 -- needed so it can be overridden by unwrapping writer protected void _depositSchemaProperty(ObjectNode propertiesNode, - JsonNode schemaNode) { + JsonNode schemaNode) { propertiesNode.set(getName(), schemaNode); } @@ -694,7 +693,7 @@ public Class[] getViews() { */ @Override public void serializeAsField(Object bean, JsonGenerator gen, - SerializerProvider prov) throws Exception { + SerializerProvider prov) throws Exception { // inlined 'get()' final Object value = (_accessorMethod == null) ? _field.get(bean) : _accessorMethod.invoke(bean, (Object[]) null); @@ -756,7 +755,7 @@ public void serializeAsField(Object bean, JsonGenerator gen, */ @Override public void serializeAsOmittedField(Object bean, JsonGenerator gen, - SerializerProvider prov) throws Exception { + SerializerProvider prov) throws Exception { if (!gen.canOmitFields()) { gen.writeOmittedField(_name.getValue()); } @@ -771,7 +770,7 @@ public void serializeAsOmittedField(Object bean, JsonGenerator gen, */ @Override public void serializeAsElement(Object bean, JsonGenerator gen, - SerializerProvider prov) throws Exception { + SerializerProvider prov) throws Exception { // inlined 'get()' final Object value = (_accessorMethod == null) ? _field.get(bean) : _accessorMethod.invoke(bean, (Object[]) null); @@ -797,7 +796,7 @@ public void serializeAsElement(Object bean, JsonGenerator gen, if (_suppressableValue != null) { if (MARKER_FOR_EMPTY == _suppressableValue) { if (ser.isEmpty(prov, value)) { // can NOT suppress entries in - // tabular output + // tabular output serializeAsPlaceholder(bean, gen, prov); return; } @@ -830,7 +829,7 @@ public void serializeAsElement(Object bean, JsonGenerator gen, */ @Override public void serializeAsPlaceholder(Object bean, JsonGenerator gen, - SerializerProvider prov) throws Exception { + SerializerProvider prov) throws Exception { if (_nullSerializer != null) { _nullSerializer.serialize(null, gen, prov); } else { @@ -847,7 +846,7 @@ public void serializeAsPlaceholder(Object bean, JsonGenerator gen, // Also part of BeanProperty implementation @Override public void depositSchemaProperty(JsonObjectFormatVisitor v, - SerializerProvider provider) throws JsonMappingException { + SerializerProvider provider) throws JsonMappingException { if (v != null) { if (isRequired()) { v.property(this); @@ -873,7 +872,7 @@ public void depositSchemaProperty(JsonObjectFormatVisitor v, @Override @Deprecated public void depositSchemaProperty(ObjectNode propertiesNode, - SerializerProvider provider) throws JsonMappingException { + SerializerProvider provider) throws JsonMappingException { JavaType propType = getSerializationType(); // 03-Dec-2010, tatu: SchemaAware REALLY should use JavaType, but alas // it doesn't... @@ -947,7 +946,7 @@ public final Object get(Object bean) throws Exception { * is no way handle it */ protected boolean _handleSelfReference(Object bean, JsonGenerator gen, - SerializerProvider prov, JsonSerializer ser) + SerializerProvider prov, JsonSerializer ser) throws IOException { if (!ser.usesObjectId()) { @@ -1000,4 +999,3 @@ public String toString() { sb.append(')'); return sb.toString(); } -} From 6ed3cda6d459ce895d3c1970b910d0bbb47f7361 Mon Sep 17 00:00:00 2001 From: Sandeep gaur Date: Sun, 29 Sep 2024 23:21:04 +0530 Subject: [PATCH 4/7] Minor chnages as per review comments --- .../jackson/databind/ser/BeanPropertyWriter.java | 15 +++++++-------- .../jackson/databind/ser/PropertyWriter.java | 7 +++++++ .../ser/impl/UnwrappingBeanPropertyWriter.java | 5 +++++ 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java b/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java index 21ad497780..6d38d98106 100644 --- a/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java +++ b/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java @@ -224,7 +224,7 @@ public BeanPropertyWriter(BeanPropertyDefinition propDef, _declaredType = declaredType; _serializer = (JsonSerializer) ser; - _dynamicSerializers = (ser == null) ? emptyForProperties() : null; + _dynamicSerializers = (ser == null) ? PropertySerializerMap.emptyForProperties() : null; _typeSerializer = typeSer; _cfgSerializationType = serType; @@ -326,9 +326,8 @@ protected BeanPropertyWriter(BeanPropertyWriter base, PropertyName name) { base._internalSettings); } _cfgSerializationType = base._cfgSerializationType; - if(base instanceof UnwrappingBeanPropertyWriter) { - _dynamicSerializers = - emptyForProperties(); + if (base.needToResetSerialization()) { + _dynamicSerializers = PropertySerializerMap.emptyForProperties(); } else { _dynamicSerializers = base._dynamicSerializers; } @@ -356,9 +355,8 @@ protected BeanPropertyWriter(BeanPropertyWriter base, SerializedString name) { base._internalSettings); } _cfgSerializationType = base._cfgSerializationType; - if(base instanceof UnwrappingBeanPropertyWriter) { - _dynamicSerializers = - emptyForProperties(); + if (base.needToResetSerialization()) { + _dynamicSerializers = PropertySerializerMap.emptyForProperties(); } else { _dynamicSerializers = base._dynamicSerializers; } @@ -470,7 +468,7 @@ Object readResolve() { _field = null; } if (_serializer == null) { - _dynamicSerializers = emptyForProperties(); + _dynamicSerializers = PropertySerializerMap.emptyForProperties(); } return this; } @@ -999,3 +997,4 @@ public String toString() { sb.append(')'); return sb.toString(); } +} \ No newline at end of file diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/PropertyWriter.java b/src/main/java/com/fasterxml/jackson/databind/ser/PropertyWriter.java index 2e6627ca8c..c200781f5c 100644 --- a/src/main/java/com/fasterxml/jackson/databind/ser/PropertyWriter.java +++ b/src/main/java/com/fasterxml/jackson/databind/ser/PropertyWriter.java @@ -100,6 +100,13 @@ public A findAnnotation(Class acls) { /********************************************************** */ + /** + * A way to reset serialization to correctly populate serializer + */ + public boolean needToResetSerialization() { + return false; + } + /** * The main serialization method called by filter when property is to be written normally. */ diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/impl/UnwrappingBeanPropertyWriter.java b/src/main/java/com/fasterxml/jackson/databind/ser/impl/UnwrappingBeanPropertyWriter.java index b701728b9e..4222f7dba1 100644 --- a/src/main/java/com/fasterxml/jackson/databind/ser/impl/UnwrappingBeanPropertyWriter.java +++ b/src/main/java/com/fasterxml/jackson/databind/ser/impl/UnwrappingBeanPropertyWriter.java @@ -224,4 +224,9 @@ protected JsonSerializer _findAndAddDynamic(PropertySerializerMap map, _dynamicSerializers = _dynamicSerializers.newWith(type, serializer); return serializer; } + + @Override + public boolean needToResetSerialization() { + return true; + } } From db03c14d76f4e488b7833becd5f5d0ede433cef4 Mon Sep 17 00:00:00 2001 From: Sandeep gaur Date: Mon, 30 Sep 2024 17:50:37 +0530 Subject: [PATCH 5/7] Minor chnages as per review comments --- .../jackson/databind/ser/BeanPropertyWriter.java | 12 ++---------- .../jackson/databind/ser/PropertyWriter.java | 8 -------- .../ser/impl/UnwrappingBeanPropertyWriter.java | 5 ----- 3 files changed, 2 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java b/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java index 6d38d98106..9abdff6430 100644 --- a/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java +++ b/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java @@ -326,11 +326,7 @@ protected BeanPropertyWriter(BeanPropertyWriter base, PropertyName name) { base._internalSettings); } _cfgSerializationType = base._cfgSerializationType; - if (base.needToResetSerialization()) { - _dynamicSerializers = PropertySerializerMap.emptyForProperties(); - } else { - _dynamicSerializers = base._dynamicSerializers; - } + _dynamicSerializers = PropertySerializerMap.emptyForProperties(); _suppressNulls = base._suppressNulls; _suppressableValue = base._suppressableValue; _includeInViews = base._includeInViews; @@ -355,11 +351,7 @@ protected BeanPropertyWriter(BeanPropertyWriter base, SerializedString name) { base._internalSettings); } _cfgSerializationType = base._cfgSerializationType; - if (base.needToResetSerialization()) { - _dynamicSerializers = PropertySerializerMap.emptyForProperties(); - } else { - _dynamicSerializers = base._dynamicSerializers; - } + _dynamicSerializers = PropertySerializerMap.emptyForProperties(); _suppressNulls = base._suppressNulls; _suppressableValue = base._suppressableValue; _includeInViews = base._includeInViews; diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/PropertyWriter.java b/src/main/java/com/fasterxml/jackson/databind/ser/PropertyWriter.java index c200781f5c..58042a2aba 100644 --- a/src/main/java/com/fasterxml/jackson/databind/ser/PropertyWriter.java +++ b/src/main/java/com/fasterxml/jackson/databind/ser/PropertyWriter.java @@ -99,14 +99,6 @@ public A findAnnotation(Class acls) { /* Serialization methods, regular output /********************************************************** */ - - /** - * A way to reset serialization to correctly populate serializer - */ - public boolean needToResetSerialization() { - return false; - } - /** * The main serialization method called by filter when property is to be written normally. */ diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/impl/UnwrappingBeanPropertyWriter.java b/src/main/java/com/fasterxml/jackson/databind/ser/impl/UnwrappingBeanPropertyWriter.java index 4222f7dba1..b701728b9e 100644 --- a/src/main/java/com/fasterxml/jackson/databind/ser/impl/UnwrappingBeanPropertyWriter.java +++ b/src/main/java/com/fasterxml/jackson/databind/ser/impl/UnwrappingBeanPropertyWriter.java @@ -224,9 +224,4 @@ protected JsonSerializer _findAndAddDynamic(PropertySerializerMap map, _dynamicSerializers = _dynamicSerializers.newWith(type, serializer); return serializer; } - - @Override - public boolean needToResetSerialization() { - return true; - } } From 53fd4109d38aa1d6011e3bab61826bdd66d11a44 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Tue, 1 Oct 2024 16:45:51 -0700 Subject: [PATCH 6/7] Update release notes --- release-notes/CREDITS-2.x | 8 ++++ release-notes/VERSION-2.x | 7 ++- .../databind/ser/BeanPropertyWriter.java | 6 +-- .../jackson/databind/ser/PropertyWriter.java | 1 + ...RecordJsonCreatorAndJsonValue4724Test.java | 43 +++++++++++++++++++ 5 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 src/test-jdk17/java/tools/jackson/databind/tofix/RecordJsonCreatorAndJsonValue4724Test.java diff --git a/release-notes/CREDITS-2.x b/release-notes/CREDITS-2.x index 6803c37e17..4ac5af603f 100644 --- a/release-notes/CREDITS-2.x +++ b/release-notes/CREDITS-2.x @@ -1837,3 +1837,11 @@ Rikkarth (rikkarth@github) Maxim Valeev (@MaximValeev) * Reported #4508: Deserialized JsonAnySetter field in Kotlin data class is null (2.18.1) + +@SandeepGaur2016 + + * Contributed fix for #2461: Nested `@JsonUnwrapped` property names not correctly handled + (2.19.0) + * Contributed fix for #4697: Inconsistent serialization with `@JsonUnwrapped` annotation + using shared vs. new `ObjectMapper` instances + (2.19.0) diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index 3165bd1449..4fed01420d 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -6,7 +6,12 @@ Project: jackson-databind 2.19.0 (not yet released) -- +#2461: Nested `@JsonUnwrapped` property names not correctly handled + (reported by @plovell) + (fix contributed by @SandeepGaur2016) +#4697: Inconsistent serialization with `@JsonUnwrapped` annotation + using shared vs. new `ObjectMapper` instances + (fix contributed by @SandeepGaur2016) 2.18.1 (WIP-2024) diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java b/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java index 9abdff6430..45ec7a0ba5 100644 --- a/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java +++ b/src/main/java/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java @@ -24,8 +24,6 @@ import com.fasterxml.jackson.databind.util.ClassUtil; import com.fasterxml.jackson.databind.util.NameTransformer; -import static com.fasterxml.jackson.databind.ser.impl.PropertySerializerMap.emptyForProperties; - /** * Base bean property handler class, which implements common parts of * reflection-based functionality for accessing a property value and serializing @@ -352,7 +350,7 @@ protected BeanPropertyWriter(BeanPropertyWriter base, SerializedString name) { } _cfgSerializationType = base._cfgSerializationType; _dynamicSerializers = PropertySerializerMap.emptyForProperties(); - _suppressNulls = base._suppressNulls; + _suppressNulls = base._suppressNulls; _suppressableValue = base._suppressableValue; _includeInViews = base._includeInViews; _typeSerializer = base._typeSerializer; @@ -989,4 +987,4 @@ public String toString() { sb.append(')'); return sb.toString(); } -} \ No newline at end of file +} diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/PropertyWriter.java b/src/main/java/com/fasterxml/jackson/databind/ser/PropertyWriter.java index 58042a2aba..2e6627ca8c 100644 --- a/src/main/java/com/fasterxml/jackson/databind/ser/PropertyWriter.java +++ b/src/main/java/com/fasterxml/jackson/databind/ser/PropertyWriter.java @@ -99,6 +99,7 @@ public A findAnnotation(Class acls) { /* Serialization methods, regular output /********************************************************** */ + /** * The main serialization method called by filter when property is to be written normally. */ diff --git a/src/test-jdk17/java/tools/jackson/databind/tofix/RecordJsonCreatorAndJsonValue4724Test.java b/src/test-jdk17/java/tools/jackson/databind/tofix/RecordJsonCreatorAndJsonValue4724Test.java new file mode 100644 index 0000000000..37e383bfc3 --- /dev/null +++ b/src/test-jdk17/java/tools/jackson/databind/tofix/RecordJsonCreatorAndJsonValue4724Test.java @@ -0,0 +1,43 @@ +package com.fasterxml.jackson.databind.tofix; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.databind.testutil.DatabindTestUtil; +import com.fasterxml.jackson.databind.testutil.failure.JacksonTestFailureExpected; + +import org.junit.jupiter.api.Test; + +// [databind#4724] Deserialization behavior change with Java Records, JsonCreator and JsonValue between 2.17.2 => 2.18.0 +public class RecordJsonCreatorAndJsonValue4724Test + extends DatabindTestUtil +{ + + public record Something(String value) { + public Something { + if (value == null || value.isEmpty()) { + throw new IllegalArgumentException("Value cannot be null or empty"); + } + } + + @JsonCreator + public static Something of(String value) { + if (value.isEmpty()) { + return null; + } + return new Something(value); + } + + @Override + @JsonValue + public String toString() { + return value; + } + } + + @JacksonTestFailureExpected + @Test + void deserialization() throws Exception { + newJsonMapper().readValue("\"\"", Something.class); + } + +} From 09d7973c8931c055241fc9407f1145c383554be0 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Tue, 1 Oct 2024 16:48:40 -0700 Subject: [PATCH 7/7] Rm accidentally added test file --- ...RecordJsonCreatorAndJsonValue4724Test.java | 43 ------------------- 1 file changed, 43 deletions(-) delete mode 100644 src/test-jdk17/java/tools/jackson/databind/tofix/RecordJsonCreatorAndJsonValue4724Test.java diff --git a/src/test-jdk17/java/tools/jackson/databind/tofix/RecordJsonCreatorAndJsonValue4724Test.java b/src/test-jdk17/java/tools/jackson/databind/tofix/RecordJsonCreatorAndJsonValue4724Test.java deleted file mode 100644 index 37e383bfc3..0000000000 --- a/src/test-jdk17/java/tools/jackson/databind/tofix/RecordJsonCreatorAndJsonValue4724Test.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.fasterxml.jackson.databind.tofix; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; -import com.fasterxml.jackson.databind.testutil.DatabindTestUtil; -import com.fasterxml.jackson.databind.testutil.failure.JacksonTestFailureExpected; - -import org.junit.jupiter.api.Test; - -// [databind#4724] Deserialization behavior change with Java Records, JsonCreator and JsonValue between 2.17.2 => 2.18.0 -public class RecordJsonCreatorAndJsonValue4724Test - extends DatabindTestUtil -{ - - public record Something(String value) { - public Something { - if (value == null || value.isEmpty()) { - throw new IllegalArgumentException("Value cannot be null or empty"); - } - } - - @JsonCreator - public static Something of(String value) { - if (value.isEmpty()) { - return null; - } - return new Something(value); - } - - @Override - @JsonValue - public String toString() { - return value; - } - } - - @JacksonTestFailureExpected - @Test - void deserialization() throws Exception { - newJsonMapper().readValue("\"\"", Something.class); - } - -}