Skip to content

Commit 9d00357

Browse files
artembilangaryrussell
authored andcommitted
Make JacksonUtils compatible with Native
* Extract inner classes for Jackson modules and use them only when respective `static boolean` is true according presence of required class in CP * Add `optional` dependencies for Jackson modules for compilation **Cherry-pick to `2.7.x`**
1 parent 9ea5cec commit 9d00357

File tree

2 files changed

+65
-48
lines changed

2 files changed

+65
-48
lines changed

build.gradle

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,12 @@ project ('spring-kafka') {
307307

308308
optionalApi 'com.fasterxml.jackson.core:jackson-core'
309309
optionalApi 'com.fasterxml.jackson.core:jackson-databind'
310+
optionalApi 'com.fasterxml.jackson.datatype:jackson-datatype-jdk8'
311+
optionalApi 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
312+
optionalApi 'com.fasterxml.jackson.datatype:jackson-datatype-joda'
313+
optionalApi ('com.fasterxml.jackson.module:jackson-module-kotlin') {
314+
exclude group: 'org.jetbrains.kotlin'
315+
}
310316

311317
// Spring Data projection message binding support
312318
optionalApi ("org.springframework.data:spring-data-commons") {
Lines changed: 59 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019 the original author or authors.
2+
* Copyright 2019-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,12 +16,10 @@
1616

1717
package org.springframework.kafka.support;
1818

19-
import org.springframework.beans.BeanUtils;
2019
import org.springframework.util.ClassUtils;
2120

2221
import com.fasterxml.jackson.databind.DeserializationFeature;
2322
import com.fasterxml.jackson.databind.MapperFeature;
24-
import com.fasterxml.jackson.databind.Module;
2523
import com.fasterxml.jackson.databind.ObjectMapper;
2624
import com.fasterxml.jackson.databind.json.JsonMapper;
2725

@@ -34,17 +32,32 @@
3432
*/
3533
public final class JacksonUtils {
3634

37-
private static final String UNUSED = "unused";
35+
private static final boolean JDK8_MODULE_PRESENT =
36+
ClassUtils.isPresent("com.fasterxml.jackson.datatype.jdk8.Jdk8Module", null);
37+
38+
private static final boolean JAVA_TIME_MODULE_PRESENT =
39+
ClassUtils.isPresent("com.fasterxml.jackson.datatype.jsr310.JavaTimeModule", null);
40+
41+
private static final boolean JODA_MODULE_PRESENT =
42+
ClassUtils.isPresent("com.fasterxml.jackson.datatype.joda.JodaModule", null);
43+
44+
private static final boolean KOTLIN_MODULE_PRESENT =
45+
ClassUtils.isPresent("kotlin.Unit", null) &&
46+
ClassUtils.isPresent("com.fasterxml.jackson.module.kotlin.KotlinModule", null);
3847

3948
/**
4049
* Factory for {@link ObjectMapper} instances with registered well-known modules
4150
* and disabled {@link MapperFeature#DEFAULT_VIEW_INCLUSION} and
4251
* {@link DeserializationFeature#FAIL_ON_UNKNOWN_PROPERTIES} features.
43-
* The {@link ClassUtils#getDefaultClassLoader()} is used for loading module classes.
4452
* @return the {@link ObjectMapper} instance.
4553
*/
4654
public static ObjectMapper enhancedObjectMapper() {
47-
return enhancedObjectMapper(ClassUtils.getDefaultClassLoader());
55+
ObjectMapper objectMapper = JsonMapper.builder()
56+
.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false)
57+
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
58+
.build();
59+
registerWellKnownModulesIfAvailable(objectMapper);
60+
return objectMapper;
4861
}
4962

5063
/**
@@ -53,63 +66,61 @@ public static ObjectMapper enhancedObjectMapper() {
5366
* {@link DeserializationFeature#FAIL_ON_UNKNOWN_PROPERTIES} features.
5467
* @param classLoader the {@link ClassLoader} for modules to register.
5568
* @return the {@link ObjectMapper} instance.
69+
* @deprecated since 2.7.5 in favor of {@link #enhancedObjectMapper()}
5670
*/
71+
@Deprecated
5772
public static ObjectMapper enhancedObjectMapper(ClassLoader classLoader) {
58-
ObjectMapper objectMapper = JsonMapper.builder()
59-
.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false)
60-
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
61-
.build();
62-
registerWellKnownModulesIfAvailable(objectMapper, classLoader);
63-
return objectMapper;
73+
return enhancedObjectMapper();
6474
}
6575

66-
@SuppressWarnings("unchecked")
67-
private static void registerWellKnownModulesIfAvailable(ObjectMapper objectMapper, ClassLoader classLoader) {
76+
private static void registerWellKnownModulesIfAvailable(ObjectMapper objectMapper) {
6877
objectMapper.registerModule(new JacksonMimeTypeModule());
69-
try {
70-
Class<? extends Module> jdk8Module = (Class<? extends Module>)
71-
ClassUtils.forName("com.fasterxml.jackson.datatype.jdk8.Jdk8Module", classLoader);
72-
objectMapper.registerModule(BeanUtils.instantiateClass(jdk8Module));
73-
}
74-
catch (@SuppressWarnings(UNUSED) ClassNotFoundException ex) {
75-
// jackson-datatype-jdk8 not available
78+
if (JDK8_MODULE_PRESENT) {
79+
objectMapper.registerModule(Jdk8ModuleProvider.MODULE);
7680
}
7781

78-
try {
79-
Class<? extends Module> javaTimeModule = (Class<? extends Module>)
80-
ClassUtils.forName("com.fasterxml.jackson.datatype.jsr310.JavaTimeModule", classLoader);
81-
objectMapper.registerModule(BeanUtils.instantiateClass(javaTimeModule));
82-
}
83-
catch (@SuppressWarnings(UNUSED) ClassNotFoundException ex) {
84-
// jackson-datatype-jsr310 not available
82+
if (JAVA_TIME_MODULE_PRESENT) {
83+
objectMapper.registerModule(JavaTimeModuleProvider.MODULE);
8584
}
8685

87-
// Joda-Time present?
88-
if (ClassUtils.isPresent("org.joda.time.LocalDate", classLoader)) {
89-
try {
90-
Class<? extends Module> jodaModule = (Class<? extends Module>)
91-
ClassUtils.forName("com.fasterxml.jackson.datatype.joda.JodaModule", classLoader);
92-
objectMapper.registerModule(BeanUtils.instantiateClass(jodaModule));
93-
}
94-
catch (@SuppressWarnings(UNUSED) ClassNotFoundException ex) {
95-
// jackson-datatype-joda not available
96-
}
86+
if (JODA_MODULE_PRESENT) {
87+
objectMapper.registerModule(JodaModuleProvider.MODULE);
9788
}
9889

99-
// Kotlin present?
100-
if (ClassUtils.isPresent("kotlin.Unit", classLoader)) {
101-
try {
102-
Class<? extends Module> kotlinModule = (Class<? extends Module>)
103-
ClassUtils.forName("com.fasterxml.jackson.module.kotlin.KotlinModule", classLoader);
104-
objectMapper.registerModule(BeanUtils.instantiateClass(kotlinModule));
105-
}
106-
catch (@SuppressWarnings(UNUSED) ClassNotFoundException ex) {
107-
//jackson-module-kotlin not available
108-
}
90+
if (KOTLIN_MODULE_PRESENT) {
91+
objectMapper.registerModule(KotlinModuleProvider.MODULE);
10992
}
11093
}
11194

11295
private JacksonUtils() {
11396
}
11497

98+
private static final class Jdk8ModuleProvider {
99+
100+
static final com.fasterxml.jackson.databind.Module MODULE =
101+
new com.fasterxml.jackson.datatype.jdk8.Jdk8Module();
102+
103+
}
104+
105+
private static final class JavaTimeModuleProvider {
106+
107+
static final com.fasterxml.jackson.databind.Module MODULE =
108+
new com.fasterxml.jackson.datatype.jsr310.JavaTimeModule();
109+
110+
}
111+
112+
private static final class JodaModuleProvider {
113+
114+
static final com.fasterxml.jackson.databind.Module MODULE =
115+
new com.fasterxml.jackson.datatype.joda.JodaModule();
116+
117+
}
118+
119+
private static final class KotlinModuleProvider {
120+
121+
static final com.fasterxml.jackson.databind.Module MODULE =
122+
new com.fasterxml.jackson.module.kotlin.KotlinModule();
123+
124+
}
125+
115126
}

0 commit comments

Comments
 (0)