skip to content

JmsTemplate

JmsTemplate sends and receives with conversion built in, resolving destinations by name or object. Interviewers point out that synchronous receive blocks a thread, and want you to prefer a listener container.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

explore

questions

5

What is Spring's JmsTemplate, and what do convertAndSend and receiveAndConvert do?

level: juniorimportance: must knowfreq 70%

answer

  1. template pattern — manages Connection/Session/Producer
  2. convertAndSend = object -> Message via MessageConverter
  3. receiveAndConvert = blocking receive -> object
  4. SimpleMessageConverter default (String/Map/Serializable/byte[])
  5. needs caching/pooled ConnectionFactory

basics

~20 s

JmsTemplate is a Spring helper that hides raw JMS boilerplate (opening connections, sessions, producers). convertAndSend turns a Java object into a JMS message and sends it; receiveAndConvert reads a message and converts it back to a Java object.

solid answer

~40 s

JmsTemplate is Spring's central class for synchronous JMS access. It follows the template pattern: you give it a ConnectionFactory, and it manages the Connection, Session, MessageProducer/MessageConsumer lifecycle for each call, so you never write try/finally cleanup. convertAndSend(destination, object) uses a MessageConverter (default SimpleMessageConverter) to marshal your object into a javax/jakarta.jms.Message and send it. receiveAndConvert(destination) does the reverse: it blocks waiting for a message, then converts the payload back to an object. Both accept either a Destination object or a String destination name resolved via a DestinationResolver. Because each operation opens and closes resources, JmsTemplate is meant to be used with a caching or pooled ConnectionFactory in production. It is thread-safe once configured.

code

java · 18 lines
java
@Service
public class OrderSender {
    private final JmsTemplate jmsTemplate;

    public OrderSender(JmsTemplate jmsTemplate) {
        this.jmsTemplate = jmsTemplate;
    }

    // convert Java object -> JMS message and send to a named queue
    public void send(Order order) {
        jmsTemplate.convertAndSend("orders.queue", order);
    }

    // blocking pull-style receive, converted back to an object
    public Order poll() {
        return (Order) jmsTemplate.receiveAndConvert("orders.queue");
    }
}

go deeper

for a junior

Know that JmsTemplate removes JMS boilerplate and that convertAndSend sends an object, receiveAndConvert reads one.

for a middle

Explain the default SimpleMessageConverter mappings and swapping in Jackson for JSON.

for a senior

Discuss the per-call resource lifecycle and why a CachingConnectionFactory is mandatory, plus receiveTimeout pitfalls.

for a principal

Frame when polling receive is the wrong tool vs. listener containers, and the operational cost model of synchronous JMS.

**JMS background.** JMS (Java/Jakarta Message Service) is the standard API for sending messages through a broker (ActiveMQ, Artemis, IBM MQ, etc.). Raw JMS is verbose: you obtain a `ConnectionFactory`, call `createConnection()`, `createSession()`, `createProducer()`/`createConsumer()`, `send`/`receive`, then close each resource in the right order inside try/finally. Getting the cleanup wrong leaks connections. **What JmsTemplate is.** `org.springframework.jms.core.JmsTemplate` implements the *template method* pattern (same idea as `JdbcTemplate`). You configure it once with a `ConnectionFactory`; each call internally does the open-session/create-producer/send/close dance for you and translates checked `JMSException`s into Spring's unchecked `JmsException` hierarchy (via `JmsTemplate`'s exception translation). Configure once (usually a Spring bean) and reuse — it is thread-safe. **Sending.** - `send(destination, MessageCreator)` — lowest level; you build the `Message` yourself in the callback. - `convertAndSend(destination, Object)` — the common path: a `MessageConverter` turns your object into a `Message`. The default is `SimpleMessageConverter`, which maps `String`→`TextMessage`, `Map`→`MapMessage`, `Serializable`→`ObjectMessage`, `byte[]`→`BytesMessage`. For JSON you swap in `MappingJackson2MessageConverter`. - `convertAndSend(dest, obj, MessagePostProcessor)` — convert, then tweak the `Message` (e.g. set a header/property) before sending. **Receiving (synchronous / polling).** - `receive(destination)` — blocks until a message arrives or `receiveTimeout` elapses, returns the raw `Message`. - `receiveAndConvert(destination)` — same, then runs the payload back through the `MessageConverter` to give you an object. - `receiveSelected(dest, selector)` — filter with a JMS selector string. This is *pull*-style consumption. For high-throughput push-style listening you normally use `@JmsListener` / `DefaultMessageListenerContainer` instead, not `JmsTemplate.receive`. **Key config knobs.** - `receiveTimeout` — default is `RECEIVE_TIMEOUT_INDEFINITE_WAIT` (0 = block forever). Almost always set a finite value, or a receive can hang a thread indefinitely. - `pubSubDomain` — `false` (default) means Queue (point-to-point); `true` means Topic (pub/sub). This flag changes how a *destination name string* is resolved. - `defaultDestination`/`defaultDestinationName` — used by the no-destination overloads. - `messageConverter`, `destinationResolver`, `sessionTransacted`, `deliveryMode`, `priority`, `timeToLive` (the last three need `explicitQosEnabled=true` to take effect). **Gotcha — connection churn.** Every send/receive opens and closes a Connection+Session against the broker. Doing that per call is expensive, so wrap the raw broker `ConnectionFactory` in a `CachingConnectionFactory` (Spring) or a pooled one (e.g. `JmsPoolConnectionFactory`) that caches connections/sessions/producers. Spring Boot auto-wires a `CachingConnectionFactory` by default. **Gotcha — receiveTimeout with caching.** A blocking `receive` holds a cached session busy; combining long/indefinite receives with a small session cache can starve producers. Prefer listener containers for continuous consumption. **When to use.** `JmsTemplate` for *request-driven, synchronous* sends and occasional polling receives; message-driven listeners for continuous async consumption.

  • What is the default MessageConverter and how do you send JSON instead?
    The default is SimpleMessageConverter (String→TextMessage, Map→MapMessage, Serializable→ObjectMessage, byte[]→BytesMessage). For JSON, register a MappingJackson2MessageConverter bean (set target type TEXT and a type-id property name); Spring Boot picks up a MessageConverter bean automatically.
  • Why should JmsTemplate not be used with the raw broker ConnectionFactory in production?
    Because each send/receive opens and closes a Connection and Session; against the raw factory that means constant connect/disconnect overhead. Wrap it in a CachingConnectionFactory (or pooled factory) so connections, sessions, and producers are reused.

saying these in an interview costs you the question

  • Thinking JmsTemplate keeps a long-lived open connection per instance (it opens/closes per operation unless the factory caches)
  • Believing receive() by default times out after a few seconds (default is block forever, 0 = indefinite)
  • Assuming convertAndSend serializes to JSON by default (default SimpleMessageConverter uses ObjectMessage/Java serialization for beans)

context

open as a page

How does JmsTemplate resolve a destination when you pass a String name, and how do queues vs topics come into play?

level: middleimportance: should knowfreq 50%

basics

~20 s

You can pass a Destination object directly, or a String name. A String is turned into a Destination by a DestinationResolver. The pubSubDomain flag decides whether that name means a queue (false) or a topic (true).

open as a page

Why does JmsTemplate need a CachingConnectionFactory, and how do sessionTransacted and receiveTimeout interact with production use?

level: seniorimportance: should knowfreq 45%

basics

~20 s

JmsTemplate opens and closes a connection and session on every call, which is slow against a raw factory. CachingConnectionFactory reuses them. receiveTimeout defaults to block-forever, so set a finite value. sessionTransacted commits/rolls back a JMS-local transaction per operation.

open as a page

What is JmsMessagingTemplate, how does it differ from JmsTemplate, and how does synchronous JMS request-reply work?

level: seniorimportance: should knowfreq 40%

basics

~20 s

JmsMessagingTemplate wraps a JmsTemplate but works with Spring's spring-messaging Message<T> abstraction (payload + headers) instead of raw JMS Message. For request-reply, convertSendAndReceive sends a message with a JMSReplyTo/correlation ID, then blocks waiting for the correlated response on a reply destination.

open as a page

When should you avoid JmsTemplate's synchronous receive and use a message-driven listener instead, and what are the architectural tradeoffs?

level: principalimportance: nice to knowfreq 25%

basics

~20 s

JmsTemplate.receive is a blocking pull that ties up a thread per call — fine for occasional request/reply, bad for continuous consumption. For steady inbound traffic use @JmsListener / DefaultMessageListenerContainer, which pushes messages, manages concurrency, and handles acks and retries.

open as a page