From 57c7053c4be7fbdfa4b5baa4e138859e1c551843 Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Mon, 8 May 2023 23:49:36 +0900 Subject: [PATCH 1/4] Add tests for regression and to prepare for rewrite --- .../RecordDeserialization3906Test.java | 154 ++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 src/test-jdk14/java/com/fasterxml/jackson/databind/failing/RecordDeserialization3906Test.java diff --git a/src/test-jdk14/java/com/fasterxml/jackson/databind/failing/RecordDeserialization3906Test.java b/src/test-jdk14/java/com/fasterxml/jackson/databind/failing/RecordDeserialization3906Test.java new file mode 100644 index 0000000000..f9bd1ada28 --- /dev/null +++ b/src/test-jdk14/java/com/fasterxml/jackson/databind/failing/RecordDeserialization3906Test.java @@ -0,0 +1,154 @@ +package com.fasterxml.jackson.databind.failing; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.BaseMapTest; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.introspect.AnnotatedClass; +import com.fasterxml.jackson.databind.introspect.NopAnnotationIntrospector; +import com.fasterxml.jackson.databind.introspect.VisibilityChecker; +import com.fasterxml.jackson.databind.module.SimpleModule; + +// [databind#3906]: Regression: 2.15.0 breaks deserialization for records when mapper.setVisibility(ALL, NONE); +public class RecordDeserialization3906Test extends BaseMapTest { + + /* + /********************************************************** + /* Set up + /********************************************************** + */ + + record Record3906(String string, int integer) { + } + + @JsonAutoDetect(creatorVisibility = Visibility.NON_PRIVATE) + record Record3906Annotated(String string, int integer) { + } + + record Record3906Creator(String string, int integer) { + @JsonCreator + Record3906Creator { + } + } + + private record PrivateRecord3906(String string, int integer) { + } + + /* + /********************************************************** + /* Failing tests that pass in 2.14 (regression) + /********************************************************** + */ + + // minimal config for reproduction + public void testEmptyJsonToRecordMiminal() throws JsonProcessingException { + ObjectMapper mapper = newJsonMapper(); + mapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE); + + Record3906 recordDeser = mapper.readValue("{}", Record3906.class); + + assertEquals(new Record3906(null, 0), recordDeser); + } + + // actual config used reproduction + public void testEmptyJsonToRecordActualImpl() throws JsonProcessingException { + ObjectMapper mapper = newJsonMapper(); + mapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE); + mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY); + + Record3906 recordDeser = mapper.readValue("{}", Record3906.class); + + assertEquals(new Record3906(null, 0), recordDeser); + } + + /* + /********************************************************** + /* Passing Tests : Suggested work-arounds + /* for future modifications + /********************************************************** + */ + + public void testEmptyJsonToRecordWorkAround() throws JsonProcessingException { + ObjectMapper mapper = newJsonMapper(); + mapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE); + mapper.setVisibility(PropertyAccessor.CREATOR, Visibility.ANY); + + Record3906 recordDeser = mapper.readValue("{}", Record3906.class); + + assertEquals(new Record3906(null, 0), recordDeser); + } + + public void testEmptyJsonToRecordCreatorsVisibile() throws JsonProcessingException { + ObjectMapper mapper = newJsonMapper(); + mapper.setVisibility(PropertyAccessor.CREATOR, Visibility.NON_PRIVATE); + + Record3906 recordDeser = mapper.readValue("{}", Record3906.class); + assertEquals(new Record3906(null, 0), recordDeser); + } + + public void testEmptyJsonToRecordUsingModule() throws JsonProcessingException { + ObjectMapper mapper = newJsonMapper().registerModule(new SimpleModule() { + @Override + public void setupModule(SetupContext context) { + super.setupModule(context); + context.insertAnnotationIntrospector(new NopAnnotationIntrospector() { + @Override + public VisibilityChecker findAutoDetectVisibility(AnnotatedClass ac, + VisibilityChecker checker) { + return ac.getType().isRecordType() + ? checker.withCreatorVisibility(JsonAutoDetect.Visibility.NON_PRIVATE) + : checker; + } + }); + } + }); + + Record3906 recordDeser = mapper.readValue("{}", Record3906.class); + assertEquals(new Record3906(null, 0), recordDeser); + } + + public void testEmptyJsonToRecordDirectAutoDetectConfig() throws JsonProcessingException { + ObjectMapper mapper = newJsonMapper(); + + Record3906Annotated recordDeser = mapper.readValue("{}", Record3906Annotated.class); + assertEquals(new Record3906Annotated(null, 0), recordDeser); + } + + public void testEmptyJsonToRecordJsonCreator() throws JsonProcessingException { + ObjectMapper mapper = newJsonMapper(); + + Record3906Creator recordDeser = mapper.readValue("{}", Record3906Creator.class); + assertEquals(new Record3906Creator(null, 0), recordDeser); + } + + public void testEmptyJsonToRecordUsingModuleOther() throws JsonProcessingException { + ObjectMapper mapper = newJsonMapper().registerModule(new SimpleModule() { + @Override + public void setupModule(SetupContext context) { + super.setupModule(context); + context.insertAnnotationIntrospector(new NopAnnotationIntrospector() { + @Override + public VisibilityChecker findAutoDetectVisibility(AnnotatedClass ac, + VisibilityChecker checker) { + if (ac.getType() == null) { + return checker; + } + if (!ac.getType().isRecordType()) { + return checker; + } + // If this is a Record, then increase the "creator" visibility again + return checker.withCreatorVisibility(Visibility.ANY); + } + }); + } + }); + + assertEquals(new Record3906(null, 0), + mapper.readValue("{}", Record3906.class)); + assertEquals(new PrivateRecord3906(null, 0), + mapper.readValue("{}", PrivateRecord3906.class)); + } +} From 32d23a4357ace20b56c6c45d515c1d81783013bf Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Mon, 8 May 2023 23:53:13 +0900 Subject: [PATCH 2/4] Add description --- .../databind/failing/RecordDeserialization3906Test.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/test-jdk14/java/com/fasterxml/jackson/databind/failing/RecordDeserialization3906Test.java b/src/test-jdk14/java/com/fasterxml/jackson/databind/failing/RecordDeserialization3906Test.java index f9bd1ada28..e1fb43793a 100644 --- a/src/test-jdk14/java/com/fasterxml/jackson/databind/failing/RecordDeserialization3906Test.java +++ b/src/test-jdk14/java/com/fasterxml/jackson/databind/failing/RecordDeserialization3906Test.java @@ -12,7 +12,12 @@ import com.fasterxml.jackson.databind.introspect.VisibilityChecker; import com.fasterxml.jackson.databind.module.SimpleModule; -// [databind#3906]: Regression: 2.15.0 breaks deserialization for records when mapper.setVisibility(ALL, NONE); +/** + * Test case that covers both failing-by-regression tests and passing tests. + *

For more details, refer to + * + * [databind#3906]: Regression: 2.15.0 breaks deserialization for records when mapper.setVisibility(ALL, NONE); + */ public class RecordDeserialization3906Test extends BaseMapTest { /* From 4d572f7a5ed2cb658b4863958334f7a9abe1d529 Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Sun, 21 May 2023 12:37:41 +0900 Subject: [PATCH 3/4] Update RecordDeserialization3906Test.java --- .../RecordDeserialization3906Test.java | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/test-jdk14/java/com/fasterxml/jackson/databind/failing/RecordDeserialization3906Test.java b/src/test-jdk14/java/com/fasterxml/jackson/databind/failing/RecordDeserialization3906Test.java index e1fb43793a..a9b0513513 100644 --- a/src/test-jdk14/java/com/fasterxml/jackson/databind/failing/RecordDeserialization3906Test.java +++ b/src/test-jdk14/java/com/fasterxml/jackson/databind/failing/RecordDeserialization3906Test.java @@ -130,26 +130,28 @@ public void testEmptyJsonToRecordJsonCreator() throws JsonProcessingException { } public void testEmptyJsonToRecordUsingModuleOther() throws JsonProcessingException { - ObjectMapper mapper = newJsonMapper().registerModule(new SimpleModule() { - @Override - public void setupModule(SetupContext context) { - super.setupModule(context); - context.insertAnnotationIntrospector(new NopAnnotationIntrospector() { + ObjectMapper mapper = jsonMapperBuilder().addModule( + new SimpleModule() { @Override - public VisibilityChecker findAutoDetectVisibility(AnnotatedClass ac, - VisibilityChecker checker) { - if (ac.getType() == null) { - return checker; - } - if (!ac.getType().isRecordType()) { - return checker; - } - // If this is a Record, then increase the "creator" visibility again - return checker.withCreatorVisibility(Visibility.ANY); + public void setupModule(SetupContext context) { + super.setupModule(context); + context.insertAnnotationIntrospector(new NopAnnotationIntrospector() { + @Override + public VisibilityChecker findAutoDetectVisibility(AnnotatedClass ac, + VisibilityChecker checker) { + if (ac.getType() == null) { + return checker; + } + if (!ac.getType().isRecordType()) { + return checker; + } + // If this is a Record, then increase the "creator" visibility again + return checker.withCreatorVisibility(Visibility.ANY); + } + }); } - }); - } - }); + }) + .build(); assertEquals(new Record3906(null, 0), mapper.readValue("{}", Record3906.class)); From 91b4d93d06f86a9f049a0746cb411cc730b1e64c Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Sun, 21 May 2023 12:40:34 +0900 Subject: [PATCH 4/4] Update RecordDeserialization3906Test.java --- .../databind/failing/RecordDeserialization3906Test.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test-jdk14/java/com/fasterxml/jackson/databind/failing/RecordDeserialization3906Test.java b/src/test-jdk14/java/com/fasterxml/jackson/databind/failing/RecordDeserialization3906Test.java index a9b0513513..dcc9a00029 100644 --- a/src/test-jdk14/java/com/fasterxml/jackson/databind/failing/RecordDeserialization3906Test.java +++ b/src/test-jdk14/java/com/fasterxml/jackson/databind/failing/RecordDeserialization3906Test.java @@ -95,7 +95,7 @@ public void testEmptyJsonToRecordCreatorsVisibile() throws JsonProcessingExcepti } public void testEmptyJsonToRecordUsingModule() throws JsonProcessingException { - ObjectMapper mapper = newJsonMapper().registerModule(new SimpleModule() { + ObjectMapper mapper = jsonMapperBuilder().addModule(new SimpleModule() { @Override public void setupModule(SetupContext context) { super.setupModule(context); @@ -109,7 +109,7 @@ public VisibilityChecker findAutoDetectVisibility(AnnotatedClass ac, } }); } - }); + }).build(); Record3906 recordDeser = mapper.readValue("{}", Record3906.class); assertEquals(new Record3906(null, 0), recordDeser);