You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2025/08/26 05:42:08 UTC
(camel) 01/01: 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.
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch jmsp
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 2b4a5eeafdd726d2b482bf421408f3756e3c002e
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Aug 26 07:41:49 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.
---
.../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()) {