Skip to content

Commit cc8f1db

Browse files
authored
GH-10058: Switch to Jackson 3 as default and deprecate Jackson 2
Fixes: #10058 * Switch to Jackson 3 classes as default * Deprecate Jackson 2 classes * Update tests and docs * Remove `UUIDJsonSerializer` in `JacksonJsonObjectMapper` * Add `@JsonCreator` to `FileMarker` and `MessageGroupMetadata` * Separate GraalVM hints for Jackson 2 & 3 * Update docs Signed-off-by: Jooyoung Pyoung <pyoungjy@gmail.com>
1 parent 6861dc7 commit cc8f1db

File tree

58 files changed

+258
-154
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+258
-154
lines changed

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,7 @@ project('spring-integration-file') {
580580
description = 'Spring Integration File Support'
581581
dependencies {
582582
api "commons-io:commons-io:$commonsIoVersion"
583+
optionalApi 'com.fasterxml.jackson.core:jackson-annotations'
583584

584585
testImplementation project(':spring-integration-redis')
585586
testImplementation project(':spring-integration-redis').sourceSets.test.output

spring-integration-core/src/main/java/org/springframework/integration/aot/CoreRuntimeHints.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,14 @@
7575
* {@link RuntimeHintsRegistrar} for Spring Integration core module.
7676
*
7777
* @author Artem Bilan
78+
* @author Jooyoung Pyoung
7879
*
7980
* @since 6.0
8081
*/
8182
class CoreRuntimeHints implements RuntimeHintsRegistrar {
8283

8384
@Override
85+
@SuppressWarnings("removal")
8486
public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
8587
ReflectionHints reflectionHints = hints.reflection();
8688
Stream.of(
@@ -103,12 +105,14 @@ public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader)
103105
reflectionHints.registerType(JsonPathUtils.class, MemberCategory.INVOKE_PUBLIC_METHODS);
104106
}
105107

108+
registerJackson2Hints(reflectionHints);
109+
106110
reflectionHints.registerType(
107-
TypeReference.of("org.springframework.integration.json.JsonPropertyAccessor$ComparableJsonNode"),
111+
TypeReference.of("org.springframework.integration.json.JacksonPropertyAccessor$ComparableJsonNode"),
108112
MemberCategory.INVOKE_PUBLIC_METHODS);
109113

110114
reflectionHints.registerType(
111-
TypeReference.of("org.springframework.integration.json.JsonPropertyAccessor$ArrayNodeAsList"),
115+
TypeReference.of("org.springframework.integration.json.JacksonPropertyAccessor$ArrayNodeAsList"),
112116
MemberCategory.INVOKE_PUBLIC_METHODS);
113117

114118
// For #xpath() SpEL function
@@ -166,4 +170,15 @@ private static void registerSpringJdkProxy(ProxyHints proxyHints, Class<?>... pr
166170
proxyHints.registerJdkProxy(AopProxyUtils.completeJdkProxyInterfaces(proxiedInterfaces));
167171
}
168172

173+
@Deprecated(since = "7.0", forRemoval = true)
174+
private static void registerJackson2Hints(ReflectionHints reflectionHints) {
175+
reflectionHints.registerType(
176+
TypeReference.of("org.springframework.integration.json.JsonPropertyAccessor$ComparableJsonNode"),
177+
MemberCategory.INVOKE_PUBLIC_METHODS);
178+
179+
reflectionHints.registerType(
180+
TypeReference.of("org.springframework.integration.json.JsonPropertyAccessor$ArrayNodeAsList"),
181+
MemberCategory.INVOKE_PUBLIC_METHODS);
182+
}
183+
169184
}

spring-integration-core/src/main/java/org/springframework/integration/config/ConverterRegistrar.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.springframework.core.convert.ConversionService;
2727
import org.springframework.core.convert.support.ConversionServiceFactory;
2828
import org.springframework.core.convert.support.GenericConversionService;
29+
import org.springframework.integration.json.JsonNodeWrapperConverter;
2930
import org.springframework.integration.json.JsonNodeWrapperToJsonNodeConverter;
3031
import org.springframework.integration.support.json.JacksonPresent;
3132
import org.springframework.integration.support.utils.IntegrationUtils;
@@ -39,6 +40,7 @@
3940
* @author Mark Fisher
4041
* @author Gary Russell
4142
* @author Artem Bilan
43+
* @author Jooyoung Pyoung
4244
*
4345
* @since 2.0
4446
*/
@@ -73,6 +75,9 @@ private void registerConverters(GenericConversionService conversionService) {
7375
.values()
7476
.stream().map(IntegrationConverterRegistration::converter)
7577
.collect(Collectors.toSet());
78+
if (JacksonPresent.isJackson3Present()) {
79+
converters.add(new JsonNodeWrapperConverter());
80+
}
7681
if (JacksonPresent.isJackson2Present()) {
7782
converters.add(new JsonNodeWrapperToJsonNodeConverter());
7883
}

spring-integration-core/src/main/java/org/springframework/integration/splitter/AbstractMessageSplitter.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
* @author Ruslan Stelmachenko
5454
* @author Gary Russell
5555
* @author Ngoc Nhan
56+
* @author Jooyoung Pyoung
5657
*/
5758
public abstract class AbstractMessageSplitter extends AbstractReplyProducingMessageHandler
5859
implements DiscardingMessageHandler {
@@ -243,10 +244,14 @@ else if (result instanceof Publisher<?> publisher) {
243244
* @return the size of the {@link Iterable}
244245
* @since 5.0
245246
*/
247+
@SuppressWarnings("removal")
246248
protected int obtainSizeIfPossible(Iterable<?> iterable) {
247249
if (iterable instanceof Collection<?> collection) {
248250
return collection.size();
249251
}
252+
else if (JacksonPresent.isJackson3Present() && JacksonTreeNodeHelper.isNode(iterable)) {
253+
return JacksonTreeNodeHelper.nodeSize(iterable);
254+
}
250255
else if (JacksonPresent.isJackson2Present() && JacksonNodeHelper.isNode(iterable)) {
251256
return JacksonNodeHelper.nodeSize(iterable);
252257
}
@@ -345,6 +350,7 @@ public String getComponentType() {
345350
*/
346351
protected abstract Object splitMessage(Message<?> message);
347352

353+
@Deprecated(since = "7.0", forRemoval = true)
348354
private static final class JacksonNodeHelper {
349355

350356
private static boolean isNode(Object object) {
@@ -357,4 +363,16 @@ private static int nodeSize(Object node) {
357363

358364
}
359365

366+
private static final class JacksonTreeNodeHelper {
367+
368+
private static boolean isNode(Object object) {
369+
return object instanceof tools.jackson.core.TreeNode;
370+
}
371+
372+
private static int nodeSize(Object node) {
373+
return ((tools.jackson.core.TreeNode) node).size();
374+
}
375+
376+
}
377+
360378
}

spring-integration-core/src/main/java/org/springframework/integration/store/MessageGroupMetadata.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import java.util.List;
2424
import java.util.UUID;
2525

26+
import com.fasterxml.jackson.annotation.JsonCreator;
27+
2628
import org.springframework.messaging.Message;
2729
import org.springframework.util.Assert;
2830

@@ -42,7 +44,7 @@ public class MessageGroupMetadata implements Serializable {
4244
private static final long serialVersionUID = 1L;
4345

4446
@SuppressWarnings("serial")
45-
private final List<UUID> messageIds = new LinkedList<>();
47+
private final List<UUID> messageIds;
4648

4749
private long timestamp;
4850

@@ -55,9 +57,16 @@ public class MessageGroupMetadata implements Serializable {
5557
private volatile String condition;
5658

5759
public MessageGroupMetadata() {
60+
this.messageIds = new LinkedList<>();
61+
}
62+
63+
@JsonCreator
64+
private MessageGroupMetadata(List<UUID> messageIds) {
65+
this.messageIds = messageIds;
5866
}
5967

6068
public MessageGroupMetadata(MessageGroup messageGroup) {
69+
this();
6170
Assert.notNull(messageGroup, "'messageGroup' must not be null");
6271
for (Message<?> message : messageGroup.getMessages()) {
6372
this.messageIds.add(message.getHeaders().getId());

spring-integration-core/src/main/java/org/springframework/integration/support/converter/ConfigurableCompositeMessageConverter.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,22 @@
2222
import java.util.stream.Collectors;
2323
import java.util.stream.Stream;
2424

25+
import tools.jackson.databind.ObjectMapper;
26+
2527
import org.springframework.beans.BeansException;
2628
import org.springframework.beans.factory.BeanFactory;
2729
import org.springframework.beans.factory.BeanFactoryAware;
2830
import org.springframework.beans.factory.InitializingBean;
2931
import org.springframework.core.convert.ConversionService;
3032
import org.springframework.core.convert.support.DefaultConversionService;
3133
import org.springframework.integration.support.json.Jackson2JsonObjectMapper;
34+
import org.springframework.integration.support.json.JacksonJsonObjectMapper;
3235
import org.springframework.integration.support.json.JacksonPresent;
3336
import org.springframework.integration.support.utils.IntegrationUtils;
3437
import org.springframework.messaging.converter.ByteArrayMessageConverter;
3538
import org.springframework.messaging.converter.CompositeMessageConverter;
3639
import org.springframework.messaging.converter.GenericMessageConverter;
40+
import org.springframework.messaging.converter.JacksonJsonMessageConverter;
3741
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
3842
import org.springframework.messaging.converter.MessageConverter;
3943

@@ -44,13 +48,14 @@
4448
* <p>
4549
* The default converts are (declared exactly in this order):
4650
* <ul>
47-
* <li> {@link MappingJackson2MessageConverter} if Jackson processor is present in classpath;
51+
* <li> {@link JacksonJsonMessageConverter} if Jackson processor is present in classpath;
4852
* <li> {@link ByteArrayMessageConverter}
4953
* <li> {@link ObjectStringMessageConverter}
5054
* <li> {@link GenericMessageConverter}
5155
* </ul>
5256
*
5357
* @author Artem Bilan
58+
* @author Jooyoung Pyoung
5459
*
5560
* @since 5.0
5661
*/
@@ -109,7 +114,13 @@ public void afterPropertiesSet() {
109114
private static Collection<MessageConverter> initDefaults() {
110115
List<MessageConverter> converters = new LinkedList<>();
111116

112-
if (JacksonPresent.isJackson2Present()) {
117+
if (JacksonPresent.isJackson3Present()) {
118+
ObjectMapper objectMapper = new JacksonJsonObjectMapper().getObjectMapper();
119+
JacksonJsonMessageConverter jsonMessageConverter = new JacksonJsonMessageConverter(objectMapper);
120+
jsonMessageConverter.setStrictContentTypeMatch(true);
121+
converters.add(jsonMessageConverter);
122+
}
123+
else if (JacksonPresent.isJackson2Present()) {
113124
MappingJackson2MessageConverter mappingJackson2MessageConverter = new MappingJackson2MessageConverter();
114125
mappingJackson2MessageConverter.setStrictContentTypeMatch(true);
115126
mappingJackson2MessageConverter.setObjectMapper(new Jackson2JsonObjectMapper().getObjectMapper());

spring-integration-core/src/main/java/org/springframework/integration/support/json/AdviceMessageJacksonDeserializer.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@
3333
* @author Ngoc Nhan
3434
*
3535
* @since 4.3.10
36+
* @deprecated Since 7.0 in favor of {@link AdviceMessageJsonDeserializer} for Jackson 3.
3637
*/
38+
@Deprecated(since = "7.0", forRemoval = true)
3739
public class AdviceMessageJacksonDeserializer extends MessageJacksonDeserializer<AdviceMessage<?>> {
3840

3941
private static final long serialVersionUID = 1L;

spring-integration-core/src/main/java/org/springframework/integration/support/json/EmbeddedJsonHeadersMessageMapper.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,9 @@
7878
* @author Artem Bilan
7979
*
8080
* @since 5.0
81-
*
81+
* @deprecated Since 7.0 in favor of {@link EmbeddedHeadersJsonMessageMapper} for Jackson 3.
8282
*/
83+
@Deprecated(since = "7.0", forRemoval = true)
8384
public class EmbeddedJsonHeadersMessageMapper implements BytesMessageMapper {
8485

8586
protected final Log logger = LogFactory.getLog(getClass()); // NOSONAR final

spring-integration-core/src/main/java/org/springframework/integration/support/json/ErrorMessageJacksonDeserializer.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@
3232
* @author Artem Bilan
3333
*
3434
* @since 4.3.10
35+
* @deprecated Since 7.0 in favor of {@link ErrorMessageJsonDeserializer} for Jackson 3.
3536
*/
37+
@Deprecated(since = "7.0", forRemoval = true)
3638
public class ErrorMessageJacksonDeserializer extends MessageJacksonDeserializer<ErrorMessage> {
3739

3840
private static final long serialVersionUID = 1L;

spring-integration-core/src/main/java/org/springframework/integration/support/json/GenericMessageJacksonDeserializer.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@
3030
* @author Artem Bilan
3131
*
3232
* @since 4.3.10
33+
* @deprecated Since 7.0 in favor of {@link GenericMessageJsonDeserializer} for Jackson 3.
3334
*/
35+
@Deprecated(since = "7.0", forRemoval = true)
3436
public class GenericMessageJacksonDeserializer extends MessageJacksonDeserializer<GenericMessage<?>> {
3537

3638
private static final long serialVersionUID = 1L;

0 commit comments

Comments
 (0)