Skip to content

Commit 9bc7cbf

Browse files
authored
Fix #372 (#373)
1 parent b46cdff commit 9bc7cbf

File tree

3 files changed

+37
-1
lines changed

3 files changed

+37
-1
lines changed

datatypes/src/main/java/com/fasterxml/jackson/datatype/jdk8/Jdk8Deserializers.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public Jdk8Deserializers() {
2626
public Jdk8Deserializers(boolean cfgReadAbsentAsNull) {
2727
_cfgReadAbsentAsNull = cfgReadAbsentAsNull;
2828
}
29-
29+
3030
@Override // since 2.7
3131
public JsonDeserializer<?> findReferenceDeserializer(ReferenceType refType,
3232
DeserializationConfig config, BeanDescription beanDesc,
@@ -52,4 +52,23 @@ public JsonDeserializer<?> findReferenceDeserializer(ReferenceType refType,
5252
}
5353
return null;
5454
}
55+
56+
// @since 2.18.5 wrt [modules-java8#372]
57+
@Override
58+
public JsonDeserializer<?> findBeanDeserializer(JavaType type,
59+
DeserializationConfig config, BeanDescription beanDesc)
60+
throws JsonMappingException
61+
{
62+
// 25-Jul-2025, tatu: [modules-java8#372] - work-around for misconfigured
63+
// `TypeFactory` that does not use `Jdk8TypeModifier`
64+
if (type.hasRawClass(Optional.class)) {
65+
// Not the cleanest but has to do: create properly resolved type;
66+
// pass `null` for `contentTypeDeserializer` and `contentDeserializer`
67+
// (to be resolver contextually)
68+
JavaType refType = config.constructType(Optional.class);
69+
return new OptionalDeserializer(refType, null, null, null,
70+
_cfgReadAbsentAsNull);
71+
}
72+
return null;
73+
}
5574
}

datatypes/src/test/java/com/fasterxml/jackson/datatype/jdk8/OptionalTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,17 @@ public void testTypeResolution() throws Exception
266266
assertTrue(t2.isCollectionLikeType());
267267
}
268268

269+
// [modules-java8#372]
270+
public void testIssue372() throws Exception
271+
{
272+
JsonNode input = MAPPER.getNodeFactory().textNode("abc");
273+
//JavaType type = MAPPER.getTypeFactory().constructType(Optional.class);
274+
JavaType type = TypeFactory.defaultInstance().constructType(Optional.class);
275+
//JavaType type = MAPPER.constructType(Optional.class);
276+
Optional<?> value = MAPPER.readValue(MAPPER.treeAsTokens(input), type);
277+
assertEquals(Optional.of("abc"), value);
278+
}
279+
269280
/*
270281
/**********************************************************
271282
/* Helper methods

release-notes/VERSION-2.x

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ Modules:
88
=== Releases ===
99
------------------------------------------------------------------------
1010

11+
2.18.5 (not yet released)
12+
13+
#372: `java.util.Optional` deserialisation fails when using `TypeFactory.defaultInstance`
14+
for creating `JavaType` for `Optional<?>`
15+
(reported by @mattlocker)
16+
1117
2.18.4 (06-May-2025)
1218

1319
#291: `InstantDeserializer` fails to parse negative numeric timestamp strings

0 commit comments

Comments
 (0)