Return to site

📩🧵 JAVA MESSAGING SERVICE (JMS) — QUEUES VS TOPICS

· jakartaee

🔸 TLDR

▪️ Queue = 1 message → 1 consumer (work distribution) ✅

▪️ Topic = 1 message → N subscribers (broadcast) 📣

▪️ Durable subscription = don’t miss messages while offline 🧷

Section image

🔸 CONTEXT (WHAT JMS IS, WITHOUT THE HYPE)

▪️ JMS is a Java API for messaging (asynchronous communication) between apps 📨

▪️ It’s about exchanging messages through a broker (ex: ActiveMQ, Artemis, IBM MQ…)

🧩 ▪️ Two main models: Queue (point-to-point) vs Topic (pub/sub) 🔀

🔸 MESSAGE QUEUES (POINT-TO-POINT) 📬

▪️ Producer sends to a queue

▪️ Consumers compete: each message is handled by only one consumer

▪️ Great for: background jobs, email sending, payments processing, retries ⚙️

Send a message to a queue

Queue queue = session.createQueue("orders.queue");
MessageProducer producer = session.createProducer(queue);

TextMessage msg = session.createTextMessage("orderId=42");
producer.send(msg);

Receive a message from a queue

Queue queue = session.createQueue("orders.queue");
MessageConsumer consumer = session.createConsumer(queue);

// blocking receive (demo purpose)
Message message = consumer.receive(5000);

if (message instanceof TextMessage tm) {
  System.out.println("Received: " + tm.getText());
} 
Browse a queue (peek without consuming) 👀
Queue queue = session.createQueue("orders.queue");
QueueBrowser browser = session.createBrowser(queue);

var enumeration = browser.getEnumeration();
while (enumeration.hasMoreElements()) {
  Message m = (Message) enumeration.nextElement();
  System.out.println("Peek message: " + m.getJMSMessageID());
}

🔸 MESSAGE TOPICS (PUBLISH / SUBSCRIBE) 📣

▪️ Producer publishes to a topic

▪️ Every subscriber gets a copy (fan-out) 🌪️

▪️ Great for: domain events, notifications, cache invalidation, audit streams 🧠

Publish to a topic

Topic topic = session.createTopic("events.topic");
MessageProducer producer = session.createProducer(topic);

producer.send(session.createTextMessage("user.signed_up id=99"));

Subscribe to a topic

Topic topic = session.createTopic("events.topic");
MessageConsumer subscriber = session.createConsumer(topic);

Message msg = subscriber.receive(5000);
System.out.println(((TextMessage) msg).getText()); 
Create a durable subscriber (don’t miss events while disconnected) 🧷
connection.setClientID("billing-service"); // required for durable sub
Topic topic = session.createTopic("events.topic");

MessageConsumer durable =
    session.createDurableSubscriber(topic, "billing-subscription");

Message msg = durable.receive(5000);
System.out.println(((TextMessage) msg).getText());

🔸 TAKEAWAYS ✅

▪️ Use Queue when you want work to be processed once (load-balanced consumers) ⚖️

▪️ Use Topic when you want broadcast (many services react to the same event) 📡

▪️ Use Durable Subscribers when subscribers must not miss messages (even offline) 🧱

▪️ JMS is an API: behavior depends on your broker + config (delivery mode, ack, redelivery…) 🔧

🔸 QUESTION FOR YOU 🤔

▪️ In your projects: are you mostly Queue-first or Topic-first?

#Java #JMS #Messaging #EventDrivenArchitecture #Integration #Microservices #Backend #Architecture #JavaDevelopers #AsyncProcessing

Go further with Java certification:

Java👇

Spring👇

SpringBook👇

JavaBook👇