Thanks so much Claus, Ashwin, and the folks in IRC over the past 2 days. It works with 2.5!
The code I used is below. I put this up on my blog for others, as well. Route and Inline Consumer // whenever message is sent to a.test, our AsyncProcessor defined here will fire from("jms:queue:a.test").process(new AsyncProcessor() { @Override public boolean process(final Exchange exchange, final AsyncCallback callback) { String body = exchange.getIn().getBody(String.class); exchange.getOut().setBody("Response: " + body); callback.done(false); return false; } @Override public void process(final Exchange exchange) throws Exception {} }); Sending message as client: // get endpoint for JMS queue defined in route above Endpoint endpoint = camelContext.getEndpoint("jms:queue:a.test"); // get producer so that we can fire messages Producer producer = endpoint.createProducer(); producer.start(); // create test message final Exchange exchange = producer.createExchange(); exchange.setPattern(ExchangePattern.InOut); DefaultMessage message = new DefaultMessage(); message.setExchange(exchange); message.setBody("test"); exchange.setIn(message); // this cast is safe because this must be a JmsProducer // .process() completes immediately; AsyncCallback instance passed in has done() called // when the consumer above has sent it's response. ((AsyncProcessor)producer).process(exchange, new AsyncCallback() { @Override public void done(final boolean b) { // our async callback. access original exchange for response body // should always check exchange.isFailed() System.out.println("Got response: " + exchange.getOut().getBody()); } }); http://www.sethcall.com/blog/2010/10/02/asynchronous-processing-with-camel-2-5-jms/