From 44c5656b710438021ea9785ad95854bff00674b2 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Mon, 4 Nov 2024 19:49:21 -0800 Subject: [PATCH] Fix #172: ignore non-Record-field properties for deser introspection (#175) --- .../com/fasterxml/jackson/jr/ob/impl/RecordsHelpers.java | 9 +++++++++ .../fasterxml/jackson/jr/ob/impl/ValueReaderLocator.java | 7 +++++++ .../java/jr/{failing => }/RecordDeser172Test.java | 2 +- release-notes/VERSION-2.x | 5 +++++ 4 files changed, 22 insertions(+), 1 deletion(-) rename jr-record-test/src/test-jdk17/java/jr/{failing => }/RecordDeser172Test.java (98%) diff --git a/jr-objects/src/main/java/com/fasterxml/jackson/jr/ob/impl/RecordsHelpers.java b/jr-objects/src/main/java/com/fasterxml/jackson/jr/ob/impl/RecordsHelpers.java index e18309fd..0b2893c2 100644 --- a/jr-objects/src/main/java/com/fasterxml/jackson/jr/ob/impl/RecordsHelpers.java +++ b/jr-objects/src/main/java/com/fasterxml/jackson/jr/ob/impl/RecordsHelpers.java @@ -1,9 +1,12 @@ package com.fasterxml.jackson.jr.ob.impl; import java.lang.reflect.Constructor; +import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Arrays; +import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import com.fasterxml.jackson.jr.ob.impl.POJODefinition.PropBuilder; @@ -80,6 +83,12 @@ static boolean isRecordType(Class cls) { return (parent != null) && "java.lang.Record".equals(parent.getName()); } + static List recordPropertyNames(Class cls) { + // Let's base this on public fields + return Arrays.asList(cls.getDeclaredFields()).stream().map(Field::getName) + .collect(Collectors.toList()); + } + private static Class[] componentTypes(Class recordType) throws ReflectiveOperationException { diff --git a/jr-objects/src/main/java/com/fasterxml/jackson/jr/ob/impl/ValueReaderLocator.java b/jr-objects/src/main/java/com/fasterxml/jackson/jr/ob/impl/ValueReaderLocator.java index 5daa77b1..0da2bd1b 100644 --- a/jr-objects/src/main/java/com/fasterxml/jackson/jr/ob/impl/ValueReaderLocator.java +++ b/jr-objects/src/main/java/com/fasterxml/jackson/jr/ob/impl/ValueReaderLocator.java @@ -456,6 +456,8 @@ protected BeanReader _resolveBeanForDeser(Class raw, POJODefinition beanDef) if (len == 0) { propMap = Collections.emptyMap(); } else { + Set recordProps = isRecord + ? new HashSet<>(RecordsHelpers.recordPropertyNames(raw)) : null; propMap = caseInsensitive ? new TreeMap<>(String.CASE_INSENSITIVE_ORDER) // 13-May-2021, tatu: Let's retain ordering here: @@ -475,6 +477,11 @@ protected BeanReader _resolveBeanForDeser(Class raw, POJODefinition beanDef) } } if (isRecord) { + // Records can only deserialize propreties that are declared in the record; + // other virtual properties (getter methods) need to be ignored + if (!recordProps.contains(rawProp.name)) { + continue; + } try { field = raw.getDeclaredField(rawProp.name); } catch (NoSuchFieldException e) { diff --git a/jr-record-test/src/test-jdk17/java/jr/failing/RecordDeser172Test.java b/jr-record-test/src/test-jdk17/java/jr/RecordDeser172Test.java similarity index 98% rename from jr-record-test/src/test-jdk17/java/jr/failing/RecordDeser172Test.java rename to jr-record-test/src/test-jdk17/java/jr/RecordDeser172Test.java index 5fd1cb6b..44beb207 100644 --- a/jr-record-test/src/test-jdk17/java/jr/failing/RecordDeser172Test.java +++ b/jr-record-test/src/test-jdk17/java/jr/RecordDeser172Test.java @@ -1,4 +1,4 @@ -package jr.failing; +package jr; import java.time.Instant; import java.time.ZoneId; diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index fd701d57..13cc23e3 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -11,6 +11,11 @@ Modules: === Releases === ------------------------------------------------------------------------ +2.18.2 (not yet released) + +#172: Record deserialisation with instance methods fails + (reported by Giovanni V-d-S) + 2.18.1 (28-Oct-2024) #167: Deserialization of record fails on constructor parameter ordering