This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch camel-4.14.x
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/camel-4.14.x by this push:
new 716ecdb98cc CAMEL-22364: camel-jms - Fix rare
ConcurrentModificationException in camel-jms due to destination produced is set
as header after sent, which can lead to a race condition when doing
request/reply over JMS and reply is already received and continued processing.
Thanks to Vladimir Dobos for the analysis. (#18996)
716ecdb98cc is described below
commit 716ecdb98cc5c3bd863b6ed078f252a3a2b4ed08
Author: Claus Ibsen <[email protected]>
AuthorDate: Tue Aug 26 10:49:07 2025 +0200
CAMEL-22364: camel-jms - Fix rare ConcurrentModificationException in
camel-jms due to destination produced is set as header after sent, which can
lead to a race condition when doing request/reply over JMS and reply is already
received and continued processing. Thanks to Vladimir Dobos for the analysis.
(#18996)
---
.../apache/camel/component/jms/JmsProducer.java | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
diff --git
a/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsProducer.java
b/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsProducer.java
index 0ce743c0138..0db06aba2d3 100644
---
a/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsProducer.java
+++
b/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsProducer.java
@@ -221,7 +221,6 @@ public class JmsProducer extends DefaultAsyncProducer {
in.setHeader(correlationPropertyToUse,
GENERATED_CORRELATION_ID_PREFIX + getUuidGenerator().generateUuid());
}
- final String to = destinationName != null ? destinationName :
getDestinationName(destination);
MessageCreator messageCreator = new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
Message answer =
endpoint.getBinding().makeJmsMessage(exchange, in, session, null);
@@ -257,12 +256,7 @@ public class JmsProducer extends DefaultAsyncProducer {
}
};
- doSend(true, destinationName, destination, messageCreator,
messageSentCallback);
-
- // record where we sent the message
- if (to != null) {
-
exchange.getMessage().setHeader(JmsConstants.JMS_DESTINATION_NAME_PRODUCED, to);
- }
+ doSend(exchange, true, destinationName, destination, messageCreator,
messageSentCallback);
// continue routing asynchronously (reply will be processed async when
its received)
return false;
@@ -399,14 +393,10 @@ public class JmsProducer extends DefaultAsyncProducer {
}
};
- doSend(false, destinationName, destination, messageCreator,
messageSentCallback);
+ doSend(exchange, false, destinationName, destination, messageCreator,
messageSentCallback);
// after sending then set the OUT message id to the JMSMessageID so
its identical
setMessageId(exchange);
- // record where we sent the message
- if (to != null) {
-
exchange.getMessage().setHeader(JmsConstants.JMS_DESTINATION_NAME_PRODUCED, to);
- }
// we are synchronous so return true
callback.done(true);
@@ -416,6 +406,7 @@ public class JmsProducer extends DefaultAsyncProducer {
/**
* Sends the message using the JmsTemplate.
*
+ * @param exchange the exchange
* @param inOut use inOut or inOnly template
* @param destinationName the destination name
* @param destination the destination (if no name provided)
@@ -423,9 +414,16 @@ public class JmsProducer extends DefaultAsyncProducer {
* @param callback optional callback to invoke when message has
been sent
*/
protected void doSend(
+ Exchange exchange,
boolean inOut, String destinationName, Destination destination,
MessageCreator messageCreator, MessageSentCallback callback) {
+ // record where we sent the message
+ String to = destinationName != null ? destinationName :
getDestinationName(destination);
+ if (to != null) {
+
exchange.getMessage().setHeader(JmsConstants.JMS_DESTINATION_NAME_PRODUCED, to);
+ }
+
CamelJmsTemplate template = (CamelJmsTemplate) (inOut ?
getInOutTemplate() : getInOnlyTemplate());
if (LOG.isTraceEnabled()) {