JMS Client
Overview
The SwiftMQ JMS 1.1 Client API provides a full-featured JMS implementation supporting point-to-point (queue) and publish/subscribe (topic) messaging, request/reply patterns, transactions (both local and XA), and all standard JMS message types. It is designed for robust, high-performance messaging with support for connection failover, duplicate message detection, and advanced configuration options. Resources such as queues, topics, and connection factories are typically obtained via JNDI lookup using SwiftMQ's conventions.
Connection Setup via JNDI
SwiftMQ JMS clients obtain ConnectionFactory, Queue, and Topic objects via JNDI lookup. The JNDI context must be configured to use the SwiftMQ provider, and connection factories are looked up using the format factoryname@routername. Queues require the format queuename@routername, while topics use just the plain topic name (no @router). The ConnectionFactory supports a wide range of configuration options, including failover, authentication, keepalives, buffer sizes, and duplicate message detection. For more details on JNDI configuration, refer to the SwiftMQ JNDI Client API documentation.
Context ctx = new InitialContext();
ConnectionFactory cf = (ConnectionFactory) ctx.lookup("myfactory@router1");
Queue queue = (Queue) ctx.lookup("orders@router1");
Topic topic = (Topic) ctx.lookup("news");
Point-to-Point Messaging (Queues)
To send and receive messages using queues, create a QueueConnection (or use a generic Connection), then create a QueueSession and use QueueSender/QueueReceiver. Queue destinations must be looked up using the queuename@routername format. Both persistent and non-persistent delivery modes are supported, as are message selectors and synchronous/asynchronous consumption. Temporary queues are supported and can be deleted by their creator session.
Queue queue = (Queue) ctx.lookup("orders@router1");
QueueConnection qc = cf.createQueueConnection();
QueueSession session = qc.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
QueueSender sender = session.createSender(queue);
QueueReceiver receiver = session.createReceiver(queue);
Publish/Subscribe Messaging (Topics)
For publish/subscribe, create a TopicConnection (or generic Connection), then a TopicSession, and use TopicPublisher/TopicSubscriber. Topics are looked up by plain name (e.g., news). Durable subscriptions are supported, requiring a client ID to be set on the connection. Temporary topics are also supported.
Topic topic = (Topic) ctx.lookup("news");
TopicConnection tc = cf.createTopicConnection();
TopicSession session = tc.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
TopicPublisher publisher = session.createPublisher(topic);
TopicSubscriber subscriber = session.createSubscriber(topic);
Request/Reply Pattern
The request/reply pattern is implemented by setting the JMSReplyTo property on a message (typically to a temporary queue or topic) and correlating replies using JMSCorrelationID. The receiver reads the JMSReplyTo destination and sends a response message to it, optionally copying over the JMSCorrelationID from the request's JMSMessageID.
// Sender
TemporaryQueue replyQueue = session.createTemporaryQueue();
TextMessage request = session.createTextMessage("request");
request.setJMSReplyTo(replyQueue);
sender.send(request);
// Receiver
Message msg = receiver.receive();
Destination replyTo = msg.getJMSReplyTo();
TextMessage reply = session.createTextMessage("response");
reply.setJMSCorrelationID(msg.getJMSMessageID());
session.createSender((Queue) replyTo).send(reply);
Transactions (Local and XA)
SwiftMQ supports both local (session-based) and XA (distributed) transactions. Local transactions are controlled via Session.commit() and Session.rollback() on transacted sessions. XA transactions are supported via XAConnection, XASession, and XAResource, with full recovery and resource manager capabilities. XA resource supports standard methods such as start, end, commit, rollback, and recover.
// Local transaction
Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
// ... send/receive messages ...
session.commit();
// XA transaction
XAConnection xac = ((XAConnectionFactory) cf).createXAConnection();
XASession xaSession = xac.createXASession();
XAResource xaRes = xaSession.getXAResource();
Message Types
All standard JMS message types are supported: TextMessage, BytesMessage, MapMessage, ObjectMessage, and StreamMessage. Each type provides the full set of JMS 1.1 methods for reading and writing body content. Messages support all standard JMS headers and properties, including custom application properties. Message property names must be valid Java identifiers.
TextMessage textMsg = session.createTextMessage("Hello");
BytesMessage bytesMsg = session.createBytesMessage();
bytesMsg.writeBytes(new byte[] {1, 2, 3});
MapMessage mapMsg = session.createMapMessage();
mapMsg.setString("key", "value");
ObjectMessage objMsg = session.createObjectMessage(mySerializableObject);
StreamMessage streamMsg = session.createStreamMessage();
streamMsg.writeInt(42);
Duplicate Message Detection and Failover
SwiftMQ supports duplicate message detection (configurable via connection factory properties) and automatic failover to backup hosts. Duplicate detection is enabled by setting the duplicate_detection_enabled property on the connection factory. Failover is configured using properties such as reconnect_enabled, reconnect_hostname2, and reconnect_port2. The client will automatically reconnect and re-establish sessions and consumers as needed.
Map<String, Object> props = new HashMap<>();
props.put("duplicate_detection_enabled", "true");
props.put("reconnect_enabled", "true");
props.put("reconnect_hostname2", "backuphost");
props.put("reconnect_port2", "4101");
ConnectionFactory cf = SwiftMQConnectionFactory.create(props);