package camelinaction; import javax.jms.JMSException; import org.apache.camel.Exchange; import org.apache.camel.component.jms.JmsMessage; import org.apache.camel.support.SynchronizationAdapter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * A Java bean that is used when using JMS Client Acknowledge Mode. * <p/> * In client mode you must explicit call the {@link javax.jms.Message#acknowledge()} method to accept the consumed * message (= commit). In case of an exception being thrown or not calling the accept, when the JMS consumer is closed, * then the message, from the JMS broker point of view is not accepted, and the message will be redelivered on next attempt. * This works in the same way as JMS Transacted Acknowledge Mode does. */ public class ClientAckBean { private static final Logger LOG = LoggerFactory.getLogger(ClientAckBean.class); public void prepareForAcknowledge(Exchange exchange) throws JMSException { // grab the javax.jms.Message from the incoming Camel JmsMessage which has the getJmsMessage() // that returns the javax.jms.Message instance final javax.jms.Message jms = exchange.getIn(JmsMessage.class).getJmsMessage(); // add UoW completion to call the JMS client acknowledge when the routing is complete (commit) // if the routing fails with an exception, then acknowledge is not called (rollback), as that exchange.addOnCompletion(new SynchronizationAdapter() { @Override public void onComplete(Exchange exchange) { LOG.info("Using JMS client acknowledge to accept the JMS message consumed: {}", jms); try { jms.acknowledge(); } catch (JMSException e) { LOG.warn("JMS client acknowledge failed due: " + e.getMessage(), e); } } }); } }