On 11/29/23 16:15, Justin Bertram wrote:
It's not clear to me that this is a defect. The JavaDoc for
JMSContext.acknowledge() [1] says (in part):

This method has identical behaviour to the acknowledge method on Message.
A client may individually acknowledge each message as it is consumed, or it
may choose to acknowledge messages as an application-defined group. In both
cases it makes no difference which of these two methods is used.

If receive() returns a null Message Object you can't invoke acknowledge on
it. Therefore, whether you use JMSContext.acknowledge() or
Message.acknowledge() the behavior will be identical - no message will be
acknowledged.

Also, it's worth noting that messages which are not acknowledged will not
be lost. In most cases they will be redelivered or in some cases may be
sent to a dead-letter address.

I believe you have skipped over the most important part of the API docs for that method which is the first sentence which states:

"Acknowledges all messages consumed by the JMSContext's session."

That would imply it works on the session level regardless of any successful (or not) calls to receive (or receiveBody which don't return actual message objects) as it is meant to work against "all message consumed by the JMSContext's session", not at the individual message level which I'd guess is indeed why it was added to the "Simplified API" as this would provide the entry point for  group acknowledge behavior described in the text.

A previously read message from the 'receive' API is in fact a consumed message within the session regardless of whether the most recent call returned a message.



Justin

[1]
https://docs.oracle.com/javaee/7/api/javax/jms/JMSContext.html#acknowledge--

On Wed, Nov 29, 2023 at 4:08 AM Андрей <x05...@gmail.com> wrote:

Hi Team,

I am currently using "artemis-jakarta-client" 2.31.2 version

I've stumbled into an issue with client acknowledge mode when using JMS
API. Here's an example:


         try (var factory = new ActiveMQConnectionFactory("<broker-url")) {
             try (var ctx = factory.createContext("<user>", "<password>",
JMSContext.CLIENT_ACKNOWLEDGE)) {
                 var destination = ctx.createQueue("<destination>");
                 try (var consumer = ctx.createConsumer(destination)) {
                     var message1 = consumer.receive(100000); // suppose
this call returns real message
                     var message2 = consumer.receive(100000); // suppose
this call times out, so NULL is returned
                     ctx.acknowledge(); // I'm expecting that message1 gets
acknowledged here, but it's not happening

                     /*
                     Do something here....
                      */

                 }
             }
         }

The reason for ack not working is that the implementation of
"consumer.receive" method stores the latest returned value in JMSContext
for future usage in its "acknowledge" method.
This happens regardless if the value is null or not. So in case latest call
returns null, all the previous messages get lost and never acked.

This seem like a defect. Am I right?

Thanks in advance


--
Tim Bish

Reply via email to