From f374ee271ec370b8c9548515ecd5038a40eda40c Mon Sep 17 00:00:00 2001 From: theghost5800 Date: Thu, 22 Oct 2026 17:04:57 +0300 Subject: [PATCH] Switch usage of Jackson v2 to v3 JIRA:LMCROSSITXSADEPLOY-3628 --- multiapps-common/pom.xml | 4 -- .../src/main/java/module-info.java | 5 +- .../multiapps/common/util/JsonUtil.java | 72 +++++++++++++------ .../multiapps/common/util/JsonUtilTest.java | 2 +- pom.xml | 7 -- 5 files changed, 54 insertions(+), 36 deletions(-) diff --git a/multiapps-common/pom.xml b/multiapps-common/pom.xml index 5b68f8b4..ad90e7e4 100644 --- a/multiapps-common/pom.xml +++ b/multiapps-common/pom.xml @@ -32,9 +32,5 @@ tools.jackson.core jackson-databind - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - diff --git a/multiapps-common/src/main/java/module-info.java b/multiapps-common/src/main/java/module-info.java index 312d0f6f..3a2b1eff 100644 --- a/multiapps-common/src/main/java/module-info.java +++ b/multiapps-common/src/main/java/module-info.java @@ -5,12 +5,11 @@ exports org.cloudfoundry.multiapps.common.util; exports org.cloudfoundry.multiapps.common.util.yaml; - requires transitive com.fasterxml.jackson.core; - requires transitive com.fasterxml.jackson.databind; requires transitive org.yaml.snakeyaml; + requires transitive tools.jackson.core; + requires transitive tools.jackson.databind; requires com.fasterxml.jackson.annotation; - requires com.fasterxml.jackson.datatype.jsr310; requires org.apache.commons.io; requires org.apache.commons.lang3; diff --git a/multiapps-common/src/main/java/org/cloudfoundry/multiapps/common/util/JsonUtil.java b/multiapps-common/src/main/java/org/cloudfoundry/multiapps/common/util/JsonUtil.java index 618feb8c..84c809e0 100644 --- a/multiapps-common/src/main/java/org/cloudfoundry/multiapps/common/util/JsonUtil.java +++ b/multiapps-common/src/main/java/org/cloudfoundry/multiapps/common/util/JsonUtil.java @@ -1,6 +1,5 @@ package org.cloudfoundry.multiapps.common.util; -import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.text.MessageFormat; @@ -16,13 +15,15 @@ import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.PropertyAccessor; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JavaType; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.ObjectWriter; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import tools.jackson.core.JacksonException; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.DeserializationFeature; +import tools.jackson.databind.JavaType; +import tools.jackson.databind.MapperFeature; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectWriter; +import tools.jackson.databind.cfg.EnumFeature; +import tools.jackson.databind.json.JsonMapper; public class JsonUtil { @@ -34,19 +35,48 @@ private JsonUtil() { } private static ObjectMapper createObjectMapper() { - return new ObjectMapper().setVisibility(PropertyAccessor.ALL, Visibility.NONE) - .setVisibility(PropertyAccessor.FIELD, Visibility.ANY) - .setSerializationInclusion(Include.NON_NULL) - .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) - .registerModule(new JavaTimeModule()); + return JsonMapper.builder() + .changeDefaultVisibility(vc -> vc.withVisibility(PropertyAccessor.ALL, Visibility.NONE) + .withVisibility(PropertyAccessor.FIELD, Visibility.ANY)) + .changeDefaultPropertyInclusion(incl -> incl.withValueInclusion(Include.NON_NULL) + .withContentInclusion(Include.NON_NULL)) + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + // Preserve Jackson 2 behavior: these defaults flipped in Jackson 3 and would change the + // byte output / read leniency of already-persisted DB-column and Flowable-variable JSON. + .disable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY) + .enable(MapperFeature.ALLOW_FINAL_FIELDS_AS_MUTATORS) + .enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS) + .enable(MapperFeature.EXTERNAL_TYPE_ID_ALWAYS_VISIBLE) + // Jackson 3 defaults to (de)serializing enums via toString(); Jackson 2 used name(). Several + // domain enums override toString() to lowercase, so keep name() to stay wire/persistence + // compatible with data written by the Jackson 2 version of the service. + .disable(EnumFeature.WRITE_ENUMS_USING_TO_STRING) + .disable(EnumFeature.READ_ENUMS_USING_TO_STRING) + .disable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS) + .disable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES) + .build(); } private static ObjectMapper createObjectMapperWithNulls() { // Visibilities are required to parse properly "immutables" objects - return new ObjectMapper().setVisibility(PropertyAccessor.ALL, Visibility.NONE) - .setVisibility(PropertyAccessor.FIELD, Visibility.ANY) - .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) - .registerModule(new JavaTimeModule()); + return JsonMapper.builder() + .changeDefaultVisibility(vc -> vc.withVisibility(PropertyAccessor.ALL, Visibility.NONE) + .withVisibility(PropertyAccessor.FIELD, Visibility.ANY)) + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + // Preserve Jackson 2 behavior: these defaults flipped in Jackson 3 and would change the + // byte output / read leniency of already-persisted DB-column and Flowable-variable JSON. + .disable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY) + .enable(MapperFeature.ALLOW_FINAL_FIELDS_AS_MUTATORS) + .enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS) + .enable(MapperFeature.EXTERNAL_TYPE_ID_ALWAYS_VISIBLE) + // Jackson 3 defaults to (de)serializing enums via toString(); Jackson 2 used name(). Several + // domain enums override toString() to lowercase, so keep name() to stay wire/persistence + // compatible with data written by the Jackson 2 version of the service. + .disable(EnumFeature.WRITE_ENUMS_USING_TO_STRING) + .disable(EnumFeature.READ_ENUMS_USING_TO_STRING) + .disable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS) + .disable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES) + .build(); } public static Map convertJsonToMap(InputStream json) { @@ -128,7 +158,7 @@ private static T fromJson(InputStream json, JsonSerializationStrategy jsonSe } try { return getObjectMapper(jsonSerializationStrategy).readValue(json, typeReference); - } catch (IOException e) { + } catch (JacksonException e) { throw new ParsingException(e, errorMessage, e.getMessage(), json); } } @@ -140,7 +170,7 @@ private static T fromJson(String json, JsonSerializationStrategy jsonSeriali } try { return getObjectMapper(jsonSerializationStrategy).readValue(json, typeReference); - } catch (IOException e) { + } catch (JacksonException e) { throw new ParsingException(e, errorMessage, e.getMessage(), json.substring(0, Math.min(json.length(), MAX_LENGTH))); } } @@ -169,7 +199,7 @@ public static String toJson(Object object, boolean indentedOutput) { public static String toJson(Object object, JsonSerializationStrategy jsonSerializationStrategy, boolean indentedOutput) { try { return getObjectWriter(jsonSerializationStrategy, indentedOutput).writeValueAsString(object); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new IllegalArgumentException(e.getMessage(), e); } } @@ -215,7 +245,7 @@ public static T fromJson(String json, JsonSerializationStrategy jsonSerializ private static T fromJson(ObjectMapper objectMapper, String json, JavaType javaType) { try { return objectMapper.readValue(json, javaType); - } catch (IOException e) { + } catch (JacksonException e) { throw new ParsingException(e, Messages.CANNOT_PARSE_JSON_STRING_TO_TYPE, json.substring(0, Math.min(json.length(), MAX_LENGTH)), diff --git a/multiapps-common/src/test/java/org/cloudfoundry/multiapps/common/util/JsonUtilTest.java b/multiapps-common/src/test/java/org/cloudfoundry/multiapps/common/util/JsonUtilTest.java index 5acbe497..87f4ef02 100644 --- a/multiapps-common/src/test/java/org/cloudfoundry/multiapps/common/util/JsonUtilTest.java +++ b/multiapps-common/src/test/java/org/cloudfoundry/multiapps/common/util/JsonUtilTest.java @@ -22,7 +22,7 @@ import org.cloudfoundry.multiapps.common.ParsingException; import org.junit.jupiter.api.Test; -import com.fasterxml.jackson.core.type.TypeReference; +import tools.jackson.core.type.TypeReference; class JsonUtilTest { diff --git a/pom.xml b/pom.xml index 16be9bd5..ed898ee2 100644 --- a/pom.xml +++ b/pom.xml @@ -27,7 +27,6 @@ 6.0.0 2.12.1 3.2.3 - 2.21.2 4.0.5 1.28.0 @@ -243,12 +242,6 @@ jackson-databind ${jackson.version} - - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - ${jackson.datatype.jsr310.version} - org.apache.commons