TL;DR
- Scenario: Java systems doing async decoupling and event-driven need unified understanding of JMS message model, object model and message types
- Conclusion: JMS is a standard API (like JDBC), key is Queue/Topic semantics, Session and acknowledgment/transaction boundaries
- Output: A directly deployable JMS basics article: concepts — object model — message types — implementation/version differences quick reference
Version Matrix
| Item | Description |
|---|---|
| JMS 2.0 | Part of Java EE 7, API still in javax.jms namespace |
| Jakarta Messaging 3.1 | Part of Jakarta EE 10, corresponding API namespace is jakarta.jms |
| ActiveMQ Classic | Full JMS 1.1 support |
| ActiveMQ Artemis | Implements own protocol, provides client-side JNDI |
| RabbitMQ | Not a JMS Provider itself, requires plugin |
JMS Mode
Basic Introduction
JMS (Java Message Service) is a standard API provided by Java platform for implementing message-oriented middleware (MOM) programming interfaces.
Core Features:
- Cross-platform: JMS provides implementation-agnostic abstract interfaces
- Loosely Coupled Communication: Decouples producers and consumers through message broker
- Supports Two Message Models:
- Point-to-Point: Based on Queue
- Publish/Subscribe: Based on Topic
JMS Messages
All JMS Message Header Fields:
- JMSMessageID
- JMSDestination
- JMSDeliveryMode
- JMSExpiration
- JMSPriority
- JMSTimestamp
- JMSCorrelationID
- JMSReplyTo
- JMSType
- JMSRedelivered
6 Standard Message Types:
- TextMessage: Most commonly used message type, contains plain string content
- ObjectMessage: Contains one serializable Java object
- MapMessage: Contains a set of key-value pair data
- BytesMessage: Contains uninterpreted byte stream data
- StreamMessage: Contains a series of Java primitive type stream data
- Message: Contains no actual data, only message headers and properties
Architecture
JMS consists of the following elements:
- JMS Provider: An implementation of JMS interface
- JMS Client: Java application that produces or consumes messages
- JMS Producer: JMS client that creates and sends messages
- JMS Consumer: JMS client that receives messages
- JMS Message: Data object passed between JMS clients
- JMS Queue: Container that caches messages
- JMS Topic: Pub/Sub mode
Object Model
Connection Factory
Connection factory is an important managed object in JMS, responsible for creating and managing connections with JMS provider:
ConnectionFactory cf = (ConnectionFactory)ctx.lookup("ConnectionFactory");
Connection connection = cf.createConnection();
Session
Represents a single-threaded context for sending and receiving messages:
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer
MessageProducer is the core interface in JMS for sending messages:
MessageProducer producer = session.createProducer(destination);
producer.send(message);
MessageConsumer
MessageConsumer is one of the core interfaces in JMS, representing message consumer:
Synchronous Receive:
Message message = consumer.receive();
Message message = consumer.receive(5000);
Asynchronous Receive:
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
// Handle message
}
});
Error Quick Reference
| Symptom | Root Cause | Fix |
|---|---|---|
NoClassDefFoundError: javax/jms/... | Dependency namespace mismatch | Unify to one API |
| Topic subscription can’t receive historical messages | Non-durable subscription only receives messages after subscription | Use durable subscription |
| Consumer keeps blocking | Didn’t call connection.start() | Call in correct order |
| Duplicate consumption | ACK/transaction boundary incorrect | Enable transaction and successfully commit |
| Message order unstable | Multiple consumers concurrent, prefetch causes disorder | Strong ordering needed: single consumer |
ObjectMessage deserialization fails | Consumer missing class with same name | Use TextMessage (JSON) |