From 75c7ac422b32cf46223a60716aaf1b3d8d7c8f99 Mon Sep 17 00:00:00 2001 From: wadhwaroh-lang Date: Sun, 26 Apr 2026 16:39:35 -0400 Subject: [PATCH] Register Expression serializer on binder ObjectMapper Restore the intended Expression serializer registration so bindings actuator output can render SpEL expressions as strings instead of traversing Expression internals. Signed-off-by: wadhwaroh-lang --- .../binder/AbstractMessageChannelBinder.java | 2 +- .../AbstractMessageChannelBinderTests.java | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/core/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/AbstractMessageChannelBinder.java b/core/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/AbstractMessageChannelBinder.java index 1a49dd8823..3a14d737c2 100644 --- a/core/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/AbstractMessageChannelBinder.java +++ b/core/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/AbstractMessageChannelBinder.java @@ -157,7 +157,7 @@ protected void onInit() throws Exception { // } SimpleModule module = new SimpleModule(); module.addSerializer(Expression.class, new ExpressionSerializer(Expression.class)); - this.objectMapper = this.objectMapper.rebuild().build(); + this.objectMapper = this.objectMapper.rebuild().addModule(module).build(); } public AbstractMessageChannelBinder(String[] headersToEmbed, PP provisioningProvider, diff --git a/core/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/AbstractMessageChannelBinderTests.java b/core/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/AbstractMessageChannelBinderTests.java index b53a8a2ac7..be19021598 100644 --- a/core/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/AbstractMessageChannelBinderTests.java +++ b/core/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/AbstractMessageChannelBinderTests.java @@ -27,6 +27,8 @@ import org.springframework.cloud.stream.provisioning.ConsumerDestination; import org.springframework.cloud.stream.provisioning.ProducerDestination; import org.springframework.context.support.GenericApplicationContext; +import org.springframework.expression.Expression; +import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.integration.core.MessageProducer; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.MessageHandler; @@ -60,6 +62,24 @@ void serializeDurationOnObjectMapperInAMCB() throws Exception { assertThat(convertedMap).isNotEmpty(); } + @Test + @SuppressWarnings("unchecked") + void serializeExpressionOnObjectMapperInAMCB() throws Exception { + AbstractMessageChannelBinder binder = createBinderInstance(); + + Field objectMapperField = ReflectionUtils.findField(AbstractMessageChannelBinder.class, "objectMapper"); + assertThat(objectMapperField).isNotNull(); + ReflectionUtils.makeAccessible(objectMapperField); + ObjectMapper objectMapper = (ObjectMapper) ReflectionUtils.getField(objectMapperField, binder); + assertThat(objectMapper).isNotNull(); + + Expression expression = new SpelExpressionParser().parseExpression("'routing.key'"); + Map properties = Map.of("routingKeyExpression", expression); + Map convertedMap = objectMapper.convertValue(properties, Map.class); + + assertThat(convertedMap).containsEntry("routingKeyExpression", "'routing.key'"); + } + @NotNull private static AbstractMessageChannelBinder createBinderInstance() throws Exception { AbstractMessageChannelBinder binder = new AbstractMessageChannelBinder<>(null, null) {