Skip to content

fix(context): snapshot message converters to prevent ConcurrentModificationException - #1445

Open
akenra wants to merge 1 commit into
spring-cloud:mainfrom
akenra:bugfix/gh-1442
Open

fix(context): snapshot message converters to prevent ConcurrentModificationException#1445
akenra wants to merge 1 commit into
spring-cloud:mainfrom
akenra:bugfix/gh-1442

Conversation

@akenra

@akenra akenra commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Hi @olegz!

This PR addresses gh-1442 - a ConcurrentModificationException in SmartCompositeMessageConverter that surfaces intermittently under concurrent load (e.g. via spring-cloud-stream's StreamBridge).

The root cause is that SmartCompositeMessageConverter iterated the live converters list returned by CompositeMessageConverter.getConverters(), while external integrations can structurally modify that same list at runtime (through SimpleFunctionRegistry.addMessageConverters()), so a fail-fast iterator racing with addAll(0, ...) throws ConcurrentModificationException.

What I did:

  • Iterate over a snapshot of the converters list taken at the start of each conversion in all five fromMessage/toMessage iteration sites, instead of the live list. getConverters() stays the live mutable list so external mutations keep working unchanged.
  • Added SmartCompositeMessageConverterTests with a deterministic reproduction: the mutation is forced to happen while the iteration is suspended (both in-loop and cross-thread via a latch handshake), so the test fails with ConcurrentModificationException on the previous code and passes with the snapshot fix.

Fixes gh-1442

…cationException

SmartCompositeMessageConverter iterated the live converters list exposed by CompositeMessageConverter.getConverters(), while external integrations such as spring-cloud-stream's StreamBridge can structurally modify that same list at runtime via SimpleFunctionRegistry.addMessageConverters(), causing a ConcurrentModificationException during toMessage()/fromMessage().

Iterate over a snapshot of the converters list taken at the start of each conversion so concurrent mutation of the underlying list no longer breaks the iteration.

Fixes spring-cloudgh-1442

Signed-off-by: akenra <37288280+akenra@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ConcurrentModificationException in SmartCompositeMessageConverter

1 participant