[ 
https://issues.apache.org/jira/browse/CAMEL-25122?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18121250#comment-18121250
 ] 

Claus Ibsen commented on CAMEL-25122:
-------------------------------------

Merged to main via https://github.com/apache/camel/pull/27031 (fix version 
4.23.0).

_Claude Code on behalf of davsclaus_

> camel-sjms - InOut: when the send fails, the request timeout completes the 
> exchange a second time (the reply handler is registered before the send and 
> never cancelled)
> -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-25122
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25122
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-sjms, camel-sjms2
>            Reporter: shashank
>            Assignee: shashank
>            Priority: Minor
>             Fix For: 4.23.0
>
>
> {{SjmsProducer.processInOut}} registers the reply handler in the correlation 
> map inside {{MessageCreator.createMessage}} 
> ({{replyManager.registerReply(...)}}), which runs before the message is sent. 
> When the send fails, the producer sets the exception and calls 
> {{callback.done(true)}}, but the handler stays registered. When the request 
> timeout expires, the timeout checker evicts it, and 
> {{ReplyManagerSupport.processReply}} completes the same exchange a second 
> time: it replaces the exception with an {{ExchangeTimedOutException}} and 
> calls {{callback.done(false)}}.
> This is the bug that CAMEL-24073 fixed in camel-jms (4.22.0). camel-sjms has 
> the same code and was not changed; its {{ReplyManager}} has no way to cancel 
> a pending reply.
> Two more cases complete the exchange twice, the other way around (the same as 
> CAMEL-25095 for camel-jms):
> * the send blocks longer than {{requestTimeout}} and then fails: the timeout 
> completes the exchange first, then the send failure completes it again;
> * the request reaches the broker and is answered, and then the send reports a 
> failure (a lost acknowledgement): the reply completes the exchange first, 
> then the send failure.
> Reproduced with a unit test in camel-sjms (embedded Artemis; the connection 
> factory is wrapped so that the send to one queue fails, no Camel code 
> changed), InOut to {{sjms:queue:...}}:
> * the send fails at once, {{requestTimeout=500}}: the exchange fails with the 
> send failure, and about 500 ms later its exception is replaced by 
> {{ExchangeTimedOutException}} (the second completion).
> * the send blocks until the request timeout has completed the exchange, then 
> fails: the caller gets the send failure instead of the 
> {{ExchangeTimedOutException}} that completed the exchange.
> * the reply arrives while the send is still running, then the send fails: the 
> caller gets the send failure although the reply had completed the exchange.
> A second completion runs the on completions of the exchange a second time 
> (such as a consumer's commit and rollback), and runs error handling on a 
> completed exchange (for camel-jms, CAMEL-25095 also showed a negative 
> inflight count; not measured here).
> h3. Proposed fix
> As in camel-jms:
> * {{ReplyManager}} gets {{boolean cancelCorrelationId(String 
> correlationId)}}, implemented by {{ReplyManagerSupport}}: it removes the 
> pending reply and returns whether it was still pending.
> * When the send fails, {{processInOut}} cancels the correlation id it 
> registered. If it was still pending, the exchange fails with the send failure 
> as before (and the timeout no longer fires). If the request timeout or the 
> reply has already removed it, they complete the exchange, so the send failure 
> is only logged at WARN, and {{processInOut}} returns without completing the 
> exchange.
> With the fix, the three cases above complete the exchange once, with the send 
> failure, the {{ExchangeTimedOutException}} and the reply respectively. The 
> new method on {{ReplyManager}} and the changed outcome of a late send failure 
> need an upgrade guide note.
> Affected: all versions of camel-sjms, and camel-sjms2, which uses the 
> camel-sjms producer (and gets the fix too).
> Duplicate check (2026-09-29): JIRA component camel-sjms since June 2025 (15 
> issues: flaky tests, CAMEL-24083 asyncConsumer, CAMEL-23646, ObjectMessage 
> and header filtering: nothing on this), text "sjms" with "timeout" and 
> "twice": nothing. CAMEL-24073 and CAMEL-25095 are camel-jms only. GitHub pull 
> requests "SjmsProducer", "sjms cancelCorrelationId": nothing on this.
> _Filed with Claude Code on behalf of allthingssecurity._



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to