Skip to content

Commit e76baf3

Browse files
committed
Update jackson to 2.16, adapt to behavioral changes
(1) Jackson adapted handling for Optional serialization providing a custom exception message if Optional is being serialized. Scout does not support serialization of Java Optional, therefore adapt test case. See also: FasterXML/jackson-databind#4082 FasterXML/jackson-databind@d7e77c3 (2) Jackson adapted handling for untyped deserialization of floating point numbers. Former implementations (before 2.15) deserialized floating point numbers within lists as BigDecimal. Since issue 903 and 3751 numbers are deserialized into the smalles possible Java data type (same behavior as plain numbers not within a JSON list element). Therefore Scout DoCollectionDeserializer was adapted identically to DoEntityDeserializer to enforce using BigDecimal for unknown (raw) number deserialization. See also: FasterXML/jackson-core#903 FasterXML/jackson-core@4c957e3 and FasterXML/jackson-databind#3751 FasterXML/jackson-databind@23ea48c 354734
1 parent 869a0da commit e76baf3

File tree

3 files changed

+47
-18
lines changed

3 files changed

+47
-18
lines changed

org.eclipse.scout.rt.jackson.test/src/test/java/org/eclipse/scout/rt/jackson/dataobject/JsonDataObjectsSerializationTest.java

+35-16
Original file line numberDiff line numberDiff line change
@@ -1796,6 +1796,24 @@ public void testSerializeDeserialize_EntityWithCollectionRaw() throws Exception
17961796
assertEquals("TestItem2", attribute7.get(1).get(ScoutDataObjectModule.DEFAULT_TYPE_ATTRIBUTE_NAME));
17971797
}
17981798

1799+
@Test
1800+
public void testSerializeDeserialize_RawEntityWithDouble() throws Exception {
1801+
DoEntity entity = BEANS.get(DoEntity.class);
1802+
entity.put("attribute", 45.69);
1803+
String json = s_dataObjectMapper.writeValueAsString(entity);
1804+
DoEntity doMarshalled = s_dataObjectMapper.readValue(json, DoEntity.class);
1805+
assertEquals(new BigDecimal("45.69"), doMarshalled.get("attribute"));
1806+
}
1807+
1808+
@Test
1809+
public void testSerializeDeserialize_RawEntityWithDoubleList() throws Exception {
1810+
DoEntity entity = BEANS.get(DoEntity.class);
1811+
entity.put("attribute", List.of(45.69));
1812+
String json = s_dataObjectMapper.writeValueAsString(entity);
1813+
DoEntity doMarshalled = s_dataObjectMapper.readValue(json, DoEntity.class);
1814+
assertEquals(new BigDecimal("45.69"), doMarshalled.getList("attribute").get(0));
1815+
}
1816+
17991817
@Test
18001818
public void testSerializeDeserialize_TestMapDo() throws Exception {
18011819
TestMapDo mapDo = new TestMapDo();
@@ -3141,27 +3159,28 @@ public void testSerializeDeserializeThrowable() throws Exception {
31413159
assertArrayEquals(exception.getStackTrace(), marshalled.getException().getStackTrace());
31423160
}
31433161

3162+
/**
3163+
* {@link Optional} is currently not serializable/deserializable using Scout Jackson implementation.
3164+
*/
31443165
@Test
31453166
public void testSerializeDeserializeOptionalDo() throws Exception {
31463167
@SuppressWarnings("unchecked")
31473168
TestOptionalDo optional = BEANS.get(TestOptionalDo.class)
3148-
.withOptString(Optional.ofNullable(null))
3149-
.withOptStringList(Optional.empty(), Optional.ofNullable("foo"));
3150-
String json = s_dataObjectMapper.writeValueAsString(optional);
3151-
3152-
// currently serializable using Scout Jackson implementation, but without values, e.g. useless!
3153-
assertJsonEquals("TestOptionalDo.json", json);
3154-
3155-
// currently not deserializable using Scout Jackson implementation
3169+
.withOptString(Optional.empty())
3170+
.withOptStringList(Optional.empty(), Optional.of("foo"));
3171+
3172+
// Expect:
3173+
// com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 optional type `java.util.Optional<java.lang.String>`
3174+
// not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jdk8" to enable handling
3175+
JsonMappingException writeException = assertThrows(JsonMappingException.class, () -> s_dataObjectMapper.writeValueAsString(optional));
3176+
assertTrue("expected InvalidDefinitionException, got " + writeException, writeException instanceof InvalidDefinitionException);
3177+
3178+
// Expect:
3179+
// com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 optional type `java.util.Optional<java.lang.String>`
3180+
// not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jdk8" to enable handling
3181+
String json = readResourceAsString("TestOptionalDo.json");
31563182
JsonMappingException exception = assertThrows(JsonMappingException.class, () -> s_dataObjectMapper.readValue(json, TestOptionalDo.class));
3157-
3158-
// TODO [23.1] pbz remove when JDK 11 is no longer supported
3159-
if ("11".equals(System.getProperty("java.specification.version"))) {
3160-
assertTrue("expected cause UnrecognizedPropertyException, got " + exception.getCause(), exception.getCause() instanceof UnrecognizedPropertyException);
3161-
}
3162-
else {
3163-
assertTrue("expected cause InvalidDefinitionException, got " + exception.getCause(), exception.getCause() instanceof InvalidDefinitionException);
3164-
}
3183+
assertTrue("expected InvalidDefinitionException, got " + exception.getCause(), exception.getCause() instanceof InvalidDefinitionException);
31653184
}
31663185

31673186
@Test

org.eclipse.scout.rt.jackson/src/main/java/org/eclipse/scout/rt/jackson/dataobject/DoCollectionDeserializer.java

+11-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
package org.eclipse.scout.rt.jackson.dataobject;
1111

1212
import java.io.IOException;
13+
import java.math.BigDecimal;
1314
import java.util.Collection;
1415
import java.util.function.Supplier;
1516

@@ -74,10 +75,19 @@ protected ResolvedType resolveListElementType(JsonParser p) {
7475
}
7576
else {
7677
// all JSON scalar values are deserialized as bound type (if available) and as fallback as raw object using default jackson typing
77-
return ObjectUtility.nvl(m_collectionType.getBindings().getBoundType(0), TypeFactory.unknownType());
78+
return ObjectUtility.nvl(m_collectionType.getBindings().getBoundType(0), resolveFallbackListElementType(p));
7879
}
7980
}
8081

82+
protected ResolvedType resolveFallbackListElementType(JsonParser p) {
83+
if (p.getCurrentToken() == JsonToken.VALUE_NUMBER_FLOAT) {
84+
// deserialize floating point numbers as BigDecimal
85+
return TypeFactory.defaultInstance().constructType(BigDecimal.class);
86+
}
87+
// JSON scalar values are deserialized as raw object using default jackson typing
88+
return TypeFactory.unknownType();
89+
}
90+
8191
@Override
8292
public Object deserializeWithType(JsonParser p, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException {
8393
return deserialize(p, ctxt);

org.eclipse.scout.rt/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@
123123
<jetty.version>10.0.15</jetty.version>
124124
<slf4j.version>2.0.7</slf4j.version>
125125
<logback.version>1.3.8</logback.version>
126-
<jackson.version>2.14.0</jackson.version>
126+
<jackson.version>2.16.0</jackson.version>
127127
<io.netty-version>4.1.94.Final</io.netty-version>
128128
<apache.tika-version>2.6.0</apache.tika-version>
129129
<batik.version>1.17</batik.version>

0 commit comments

Comments
 (0)