diff --git a/datatypes/src/main/java/com/fasterxml/jackson/datatype/jdk8/Jdk8Deserializers.java b/datatypes/src/main/java/com/fasterxml/jackson/datatype/jdk8/Jdk8Deserializers.java index ea1f6e53..5e46b9fb 100644 --- a/datatypes/src/main/java/com/fasterxml/jackson/datatype/jdk8/Jdk8Deserializers.java +++ b/datatypes/src/main/java/com/fasterxml/jackson/datatype/jdk8/Jdk8Deserializers.java @@ -26,7 +26,7 @@ public Jdk8Deserializers() { public Jdk8Deserializers(boolean cfgReadAbsentAsNull) { _cfgReadAbsentAsNull = cfgReadAbsentAsNull; } - + @Override // since 2.7 public JsonDeserializer findReferenceDeserializer(ReferenceType refType, DeserializationConfig config, BeanDescription beanDesc, @@ -52,4 +52,23 @@ public JsonDeserializer findReferenceDeserializer(ReferenceType refType, } return null; } + + // @since 2.18.5 wrt [modules-java8#372] + @Override + public JsonDeserializer findBeanDeserializer(JavaType type, + DeserializationConfig config, BeanDescription beanDesc) + throws JsonMappingException + { + // 25-Jul-2025, tatu: [modules-java8#372] - work-around for misconfigured + // `TypeFactory` that does not use `Jdk8TypeModifier` + if (type.hasRawClass(Optional.class)) { + // Not the cleanest but has to do: create properly resolved type; + // pass `null` for `contentTypeDeserializer` and `contentDeserializer` + // (to be resolver contextually) + JavaType refType = config.constructType(Optional.class); + return new OptionalDeserializer(refType, null, null, null, + _cfgReadAbsentAsNull); + } + return null; + } } diff --git a/datatypes/src/test/java/com/fasterxml/jackson/datatype/jdk8/OptionalTest.java b/datatypes/src/test/java/com/fasterxml/jackson/datatype/jdk8/OptionalTest.java index a640e924..a36c8740 100644 --- a/datatypes/src/test/java/com/fasterxml/jackson/datatype/jdk8/OptionalTest.java +++ b/datatypes/src/test/java/com/fasterxml/jackson/datatype/jdk8/OptionalTest.java @@ -266,6 +266,17 @@ public void testTypeResolution() throws Exception assertTrue(t2.isCollectionLikeType()); } + // [modules-java8#372] + public void testIssue372() throws Exception + { + JsonNode input = MAPPER.getNodeFactory().textNode("abc"); + //JavaType type = MAPPER.getTypeFactory().constructType(Optional.class); + JavaType type = TypeFactory.defaultInstance().constructType(Optional.class); + //JavaType type = MAPPER.constructType(Optional.class); + Optional value = MAPPER.readValue(MAPPER.treeAsTokens(input), type); + assertEquals(Optional.of("abc"), value); + } + /* /********************************************************** /* Helper methods diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index f59b881b..b037e58f 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -8,6 +8,12 @@ Modules: === Releases === ------------------------------------------------------------------------ +2.18.5 (not yet released) + +#372: `java.util.Optional` deserialisation fails when using `TypeFactory.defaultInstance` + for creating `JavaType` for `Optional` + (reported by @mattlocker) + 2.18.4 (06-May-2025) #291: `InstantDeserializer` fails to parse negative numeric timestamp strings