Vladimir Dobos created CAMEL-22364:
--------------------------------------
Summary: ConcurrentModificationException on message header map
when using multiple camel-jms calls after each other in route
Key: CAMEL-22364
URL: https://issues.apache.org/jira/browse/CAMEL-22364
Project: Camel
Issue Type: Bug
Components: camel-jms
Affects Versions: 4.14.0, 4.13.0, 4.12.0, 4.11.0, 4.10.6, 4.9.0, 4.8.8,
4.6.0, 4.5.0, 4.4.5
Reporter: Vladimir Dobos
Attachments: access_history.txt, camel.log
When calling multiple camel-jms endpoints in sequence in one route, there is a
random possibility of ConcurrentModificationException on header map during
route execution when using more than 1 thread to run the route (see stacktrace
on line 12 in attached log file camel.log) for details.
I wrote simple program to simulate the issue
(https://github.com/vdobos-tr/TestJmsConcurrentModification), program contains
both client (RageCallMQ.java using jmh, run by jmh.sh) and backend (CamelMain,
executed usually from my IDE) part, client uses JMH to tax the camel-jms
endpoints and cause the exception. We use IBM MQ as a message broker (added
example compose in directory mq-compose, requires path modification to run).
Probability and time until the exception happens depends heavily on hardware
and general setup of the host machine. Our customers can easily replicate the
issue in their test environments running 20 consumers and simple route
(from(jms, in only).process().to(jms, inout).process(...).to(jms, out only))
whereas we had to run 50-75 threads and up to 6 orchestrations to get one
exception within 30 minutes of execution (from(jms, in only).process().[to(jms,
inout).process(...)<repeat 6 times>].to(jms, out only)). As a race condition,
unfortunatelly, the timing when the exception occuring is very random,
sometimes it can occur within first minute, sometimes it can take 30+ minutes
:(.
Exception occurs regardless if CachingConnectionFactory is used and regardles
of asyncConsumer setting. ConcurrentModificationException is caused by parallel
acces of two threads to headers map on message (I used custom HeadersMapFactory
and custom map implementation with some Proxy classes to trace the issue, see
package cz.trask.bi.mq.camel.debugmap in application)
I was able to trace the issue to change in camel 4.4.0
(https://issues.apache.org/jira/browse/CAMEL-20338, see file
access_history.txt, lines 78 to 200 and line 202 created by custom Headers Map
that shows thread acces causing the issue).
As far as I understand the problem, it is posible for doSend(...) on line 260
in JmsProducer to not finish (maybe OS schduler parking threads ?) until next
thread processing next part of route received response from backend and is
already sending next request (or final response) in route (header map iteration
on line 368 of JmsBinfding, where the stacktrace originates), during this
iteration original doSend(...) on line on line 260 in JmsProducer resumes and
hits lines 260-262, added by CAMEL-20338, causing
ConcurrentModificationException on next loop iteration in JmsBinding, line 368.
I tested the issue on camel 4.4.0, 4.8.3 - the version of apache camel we and
our customers are currently using, 4.10.6, 4.13.0 and also newly relased 4.14.0
and it occurs on all of them.
Apache camel releases before canel 4.4.0 (4.3.0, 4.2.0, 4.1.0, 4.0.0) do not
manifest the issue.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)