Description
This issue has been observed with Spring Integration Core version 6.3.0.
Detailed Versioning Summary
-
Before Upgrade:
- Java version: 17
- Spring Boot version: 3.0.1
- spring-boot-starter-integration: 3.0.1
- spring-integration-core: 6.0.1
-
After Upgrade:
- Java version: 21
- Spring Boot version: 3.3.0
- spring-boot-starter-integration: 3.3.0
- spring-integration-core: 6.3.0
Background and Problem Details
Our project was updated from Java 17 to Java 21 and from spring-integration-core:6.0.1 to 6.3.0.
So in our Spring Integration setup, we implemented a custom ThreadStatePropagationChannelInterceptor to manage MDC (Mapped Diagnostic Context) propagation across asynchronous message channels. However, after the update -- especically spring-integration-core:6.3.0, we began encountering ConcurrentModificationException errors during message processing.Additionally, this only occurs when the application is in debug mode.
Exception Stack Trace
Caused by: java.util.ConcurrentModificationException at java.base/java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:977) ~[?:?] at java.base/java.util.LinkedList$ListItr.next(LinkedList.java:899) ~[?:?] at java.base/java.util.AbstractCollection.toString(AbstractCollection.java:458) ~[?:?] at java.base/java.lang.StringConcatHelper.stringOf(StringConcatHelper.java:467) ~[?:?] at org.springframework.integration.channel.interceptor.ThreadStatePropagationChannelInterceptor$MessageWithThreadState.toString(ThreadStatePropagationChannelInterceptor.java:134) ~[spring-integration-core-6.3.0.jar!/:6.3.0] at java.base/java.lang.StringConcatHelper.stringOf(StringConcatHelper.java:467) ~[?:?] at org.springframework.integration.channel.AbstractMessageChannel.sendInternal(AbstractMessageChannel.java:381) ~[spring-integration-core-6.3.0.jar!/:6.3.0] at org.springframework.integration.channel.AbstractMessageChannel.sendWithMetrics(AbstractMessageChannel.java:349) ~[spring-integration-core-6.3.0.jar!/:6.3.0] at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:329) ~[spring-integration-core-6.3.0.jar!/:6.3.0] at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:302) ~[spring-integration-core-6.3.0.jar!/:6.3.0]
Screenshot from where this expection is being raised
This Screen shot shows that when the application runs in debug mode, a toString method on **messageToSend** is invoked. where, messageToSend contains an implementation of ThreadStatePropagationInterceptor
Analysis :
To Reproduce
Ensure your project is using Spring Integration Core version 6.3.0.
Implement a custom ThreadStatePropagationChannelInterceptor for context propagation.
Run the application in debug mode and send messages through an integration flow that routes messages to couple of asynchronous channels. Monitor for any ConcurrentModificationException during message processing.
Expected behavior
Concurrent access to stateQueue should not result in a ConcurrentModificationException. Ideally, stateQueue would be thread-safe to support multi-threaded access during message processing.