0
votes

I am unable to acknowledge JMS message with CLIENT_ACKNOWLEDGE mode in camel. After digging a into the stack trace I found that message.acknowledge() in AbstractMessageListenerContainer is always being executed which causes the auto-ack behavior. Am I configured anything wrong?

org.springframework.jms.listener.AbstractMessageListenerContainer.commitIfNecessary(Session, Message)

protected void commitIfNecessary(Session session, Message message) throws JMSException {
        // Commit session or acknowledge message.
        if (session.getTransacted()) {
            // Commit necessary - but avoid commit call within a JTA transaction.
            if (isSessionLocallyTransacted(session)) {
                // Transacted session created by this container -> commit.
                JmsUtils.commitIfNecessary(session);
            }
        }
        else if (message != null && isClientAcknowledge(session)) {
            message.acknowledge();
        }
    }

Spring Configuration

<bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
    <property name="connectionFactory" ref="cachedConnectionFactory" />
    <property name="asyncConsumer" value="true" />
    <property name="acknowledgementModeName" value="CLIENT_ACKNOWLEDGE" />
</bean>

<bean id="cachedConnectionFactory"
    class="org.springframework.jms.connection.CachingConnectionFactory">
    <property name="targetConnectionFactory" ref="connectionFactory" />
    <property name="sessionCacheSize" value="30" />
</bean>

Camel Route

from(jmsTerminalRequest).routeId("generic-jms-inbound").setExchangePattern(ExchangePattern.InOnly).threads(5, 20, "generic-jms-inbound").bean(clientAckProcessor).to("...")
1
What is the problem? camel-jms uses spring which has that auto ack functionality.Claus Ibsen
The problem is on the client ack. If the client ack is done before creating the threads, it works fine. i.e. from(jmsTerminalRequest).routeId("generic-jms-inbound").setExchangePattern(ExchangePattern.InOnly).bean(clientAckProcessor).threads(5, 20, "generic-jms-inbound").to("...")Lewis Wong
Use concurrentConsumers=5&maxConcurrentConsumers=20 on the from JMX endpoint instead of threads(5,20) and it should workClaus Ibsen
Thanks. However, the vendor only provides JMS1.x spec which doesn't support maxConcurrentConsumers option. No matter what you set, it just run in single thread.Lewis Wong

1 Answers

1
votes

What you can do is specifying acknowledgement mode within route consuming endpoint definition:

from("...?maxConcurrentConsumers=20&acknowledgementModeName=CLIENT_ACKNOWLEDGE")
    .bean(clientAckProcessor)
    .to("...")