Skip to content

JMS Swiftlet

Overview

The JMS Swiftlet implements the core Java Message Service (JMS) protocol support for SwiftMQ routers, enabling JMS clients to connect, authenticate, and interact with queues and topics. It manages client connections, sessions, producers, consumers, and provides mechanisms for message delivery, acknowledgment, transactions, and durable subscriptions. The Swiftlet also exposes configuration for connection factories, listeners, and connection/session resource limits.

Features

JMS Connection Management

The JMS Swiftlet manages all incoming JMS client connections, enforcing resource limits and handling authentication via a pluggable challenge/response mechanism. Each connection is tracked and can be limited globally or per-listener using the max-connections property. The Swiftlet ensures that each JMS client ID is unique by default, but this can be relaxed via the allow-same-clientid property. Connections are monitored for activity and can be disconnected if keep-alive intervals are exceeded.

Client ID Enforcement

By default, only one connection per JMS client ID is allowed. This prevents duplicate client IDs across connections, which is a JMS requirement. The allow-same-clientid property can be set to true to permit multiple connections using the same client ID, which may be useful in certain failover or testing scenarios.

Authentication and Challenge/Response

Authentication is performed using a configurable challenge/response factory, specified by the crfactory-class property. This allows integration with custom authentication mechanisms.

Per-Listener Resource Limits

Each listener can specify its own max-connections property, limiting the number of concurrent connections accepted on that listener.

Configuration Example:

<swiftlet name="sys$jms" allow-same-clientid="true" max-connections="100" crfactory-class="com.example.CustomCRFactory"/>

Listener and Connection Factory Configuration

Listeners define network endpoints (IP/port) on which the JMS Swiftlet accepts client connections. Each listener can have multiple connection factories, which define client connection parameters such as buffer sizes, reconnect behavior, and default JMS message properties. Host access lists can be set per listener to restrict which remote hosts may connect. Connection factories are registered in JNDI for client lookup.

High Availability (HA) Support

Listeners and connection factories support configuration for a secondary (HA) instance, including alternate hostnames and ports, allowing clients to failover between primary and secondary endpoints.

Host Access Control

Each listener can define a host-access-list to restrict inbound connections to specific hosts or address patterns.

Configuration Example:

<swiftlet name="sys$jms">
  <listeners>
    <listener name="listener1" port="4001">
      <host-access-list>
        <host-access-entry name="192.168.1.%"/>
      </host-access-list>
      <connection-factories>
        <connection-factory name="cf1" smqp-consumer-cache-size="1000" reconnect-enabled="false"/>
      </connection-factories>
    </listener>
  </listeners>
</swiftlet>

JMS Session, Producer, and Consumer Lifecycle

For each active connection, the JMS Swiftlet manages the lifecycle of JMS sessions, producers, and consumers. Sessions can be transacted or non-transacted, and support all standard JMS acknowledgment modes. Producers and consumers are tracked per session, and resource limits are enforced. Consumers can use message selectors for filtering, and both queue and topic semantics are supported.

Queue and Topic Support

Sessions can create producers and consumers for both queues and topics, including temporary destinations. Topic subscriptions support both non-durable and durable modes.

Message Selectors

Consumers and browsers can specify SQL-like message selectors to filter messages. Selectors are compiled and validated at consumer creation.

Temporary Queues and Durable Subscriptions

JMS clients can create temporary queues for the lifetime of their connection. The Swiftlet manages the lifecycle of these queues, ensuring they are deleted when the connection closes. Durable topic subscriptions are supported, with queues named according to the <clientId>$<durableName> pattern.

Temporary Queue Naming

Temporary queues are named using the pattern tmp$<sequence>-<startuptime>, ensuring uniqueness per router instance.

Durable Subscription Queues

Durable subscriptions are backed by queues named <clientId>$<durableName>, allowing persistent delivery of topic messages to offline subscribers.

Queue Browsers and Message Selectors

The JMS Swiftlet supports queue browsers, allowing clients to browse messages on a queue without consuming them. Browsers can use message selectors to filter which messages are visible during browsing sessions.

Browser Entity Tracking

Browsers are tracked per session, and their lifecycle is managed by the Swiftlet. Each browser is associated with a unique ID and can be closed independently.

Transactional Message Processing

The JMS Swiftlet fully supports JMS transactions for both queue and topic sessions. The transaction manager coordinates commit and rollback operations, ensuring atomic delivery and acknowledgment of messages. Producers and consumers enlisted in a session's transaction are managed together, and the Swiftlet handles resource cleanup and recovery in case of rollback or failover.

Composite Store Transactions

For persistent messages, the transaction manager uses composite store transactions to ensure atomicity across multiple queues.

Connection and Message Statistics

The Swiftlet collects and exposes statistics such as messages sent/received per connection, as well as total message counts. The collection interval is configurable via the collect-interval property. These statistics are available for monitoring and management purposes.

Dynamic Usage Entities

Active connections and their sessions, producers, and consumers are represented as dynamic entities under the usage entity list, providing real-time visibility into JMS activity.

Configuration Example:

<swiftlet name="sys$jms" collect-interval="2000"/>

Internal Queue Naming

  • tmp$<sequence>-<startuptime> — Temporary queue created for a JMS connection; used for temporary destinations.
  • <clientId>$<durableName> — Queue backing a durable topic subscription for a given client ID and durable name.

Configuration Guide

Restricting Connections to Specific Hosts

To limit which remote hosts can connect to a JMS listener, use the host-access-list to specify allowed address patterns. This is useful for security or network segmentation.

  1. Edit the routerconfig.xml and locate the desired listener under the sys$jms swiftlet.
  2. Add host-access-entry elements with the desired address patterns (e.g., 192.168.1.% for a subnet).
  3. Restart the router or reload configuration if necessary.
<swiftlet name="sys$jms">
  <listeners>
    <listener name="listener1" port="4001">
      <host-access-list>
        <host-access-entry name="192.168.1.%"/>
        <host-access-entry name="10.0.0.5"/>
      </host-access-list>
    </listener>
  </listeners>
</swiftlet>

Configuring a Custom Challenge/Response Authentication Factory

To integrate a custom authentication mechanism for JMS clients, set the crfactory-class property to your implementation. This allows the Swiftlet to use your class for challenge/response authentication.

  1. Implement a class that extends the ChallengeResponseFactory interface.
  2. Set the crfactory-class property in the sys$jms swiftlet configuration to the fully qualified class name.
  3. Restart the router to apply the change.
<swiftlet name="sys$jms" crfactory-class="com.example.CustomCRFactory"/>

Limiting the Number of JMS Connections

To prevent resource exhaustion, set global or per-listener limits on the number of concurrent JMS connections.

  1. Set the max-connections property on the sys$jms swiftlet for a global limit.
  2. Alternatively, set the max-connections property on individual listeners for per-listener limits.
  3. Save the configuration and restart the router if required.
<swiftlet name="sys$jms" max-connections="50">
  <listeners>
    <listener name="listener1" port="4001" max-connections="10"/>
  </listeners>
</swiftlet>

Configuration Reference

The top-level entity in routerconfig.xml is <swiftlet name="sys$jms">.

<swiftlet name="sys$jms"> Properties

These properties are attributes of the <swiftlet name="sys$jms"> entity.

Parameter Type Default Mandatory Reboot Required Description
allow-same-clientid Boolean false No No Allows multiple connection with the same JMS Client Id if set to true
collect-interval Long 10000 No No Collect Interval Messages/Sec
max-connections Integer -1 No No Maximum JMS Connections
consumer-cache-low-water-mark Integer 100 No No Consumer caches are refilled when reaching this mark (min: 0)
crfactory-class String com.swiftmq.auth.ChallengeResponseFactoryImpl No Yes Challenge/Response Factory Class
<swiftlet name="sys$jms" allow-same-clientid="false" collect-interval="10000" max-connections="-1" consumer-cache-low-water-mark="100" crfactory-class="com.swiftmq.auth.ChallengeResponseFactoryImpl"/>

<intravm-connection-factories> in <swiftlet name="sys$jms">

IntraVM Connection Factories

Each <intravm-connection-factory> entry is identified by its name attribute (the IntraVM Connection Factory).

Parameter Type Default Mandatory Reboot Required Description
smqp-producer-reply-interval Integer 20 Yes No Number of SMQP Requests after which a SMQP Reply is required (min: 1)
smqp-consumer-cache-size Integer 500 Yes No Cache Size per Consumer (Messages) (min: 1)
smqp-consumer-cache-size-kb Integer 2048 Yes No Cache Size per Consumer (KB)
jms-client-id String No No JMS Client Id for durable Subscribers
jms-default-delivery-mode String persistent Yes No JMS Default Delivery Mode (choices: persistent, non_persistent)
jms-default-message-ttl Long 0 Yes No JMS Default Message TTL (min: 0)
jms-default-message-priority Integer 4 Yes No JMS Default Message Priority (range: 0–9)
jms-default-message-id-enabled Boolean true No No JMS Default Message Id Enabled
jms-default-message-timestamp-enabled Boolean true No No JMS Default Message Timestamp Enabled
thread-context-classloader-for-getobject Boolean false No No Use the Thread Context Classloader for getObject()
<swiftlet name="sys$jms">
  <intravm-connection-factories>
    <intravm-connection-factory name="..." smqp-producer-reply-interval="..." smqp-consumer-cache-size="..." smqp-consumer-cache-size-kb="..." jms-default-delivery-mode="..." jms-default-message-ttl="..." jms-default-message-priority="..."/>
  </intravm-connection-factories>
</swiftlet>

<listeners> in <swiftlet name="sys$jms">

Listener Definitions

Each <listener> entry is identified by its name attribute (the Listener).

Parameter Type Default Mandatory Reboot Required Description
connectaddress String No No Listener Connect IP Address for NAT
connectport Integer -1 No No Listener Connect Port for NAT
bindaddress String No No Listener Bind IP Address
port Integer Yes No Listener Port
hostname2 String No No Hostname of the 2nd HA Instance
connectaddress2 String No No Listener Connect IP Address for NAT of the 2nd HA Instance
connectport2 Integer -1 No No Listener Connect Port for NAT of the 2nd HA Instance
bindaddress2 String No No Listener Bind IP Address of the 2nd HA Instance
port2 Integer -1 No No Listener Port 2nd HA Instance of the 2nd HA Instance
use-tcp-no-delay Boolean true Yes No Use Tcp No Delay
socketfactory-class String com.swiftmq.net.PlainSocketFactory No No Listener Socketfactory Class
keepalive-interval Long 60000 No No Interval for sending Keep Alive Messages
max-connections Integer -1 No No Maximum JMS Connections for this Listener
router-input-buffer-size Integer 131072 No No Router Network Input Buffer Size (min: 1024)
router-input-extend-size Integer 65536 No No Router Network Input Extend Size (min: 1024)
router-output-buffer-size Integer 131072 No No Router Network Output Buffer Size (min: 1024)
router-output-extend-size Integer 65536 No No Router Network Output Extend Size (min: 1024)
<swiftlet name="sys$jms">
  <listeners>
    <listener name="..." port="..." use-tcp-no-delay="..."/>
  </listeners>
</swiftlet>

<host-access-list> in <listeners>

Host Access List

Each <host-access-entry> entry is identified by its name attribute (the Host Access Entry).

<swiftlet name="sys$jms">
  <listeners>
    <listener name="...">
      <host-access-list>
        <host-access-entry name="..."/>
      </host-access-list>
    </listener>
  </listeners>
</swiftlet>

<connection-factories> in <listeners>

Connection Factories

Each <connection-factory> entry is identified by its name attribute (the Connection Factory).

Parameter Type Default Mandatory Reboot Required Description
reconnect-enabled Boolean true No No Reconnect Enabled
reconnect-max-retries Integer 10 No No Maximum Retries for Reconnect
reconnect-delay Long 10000 No No Reconnect Delay in ms
duplicate-message-detection Boolean true No No Enables Duplicate Message Detection for Consumers
duplicate-backlog-size Integer 2000 No No Max. Number of Entries of JMS Message IDs in the Duplicate Backlog
client-input-buffer-size Integer 131072 No No Client Network Input Buffer Size (min: 1024)
client-input-extend-size Integer 65536 No No Client Network Input Extend Size (min: 1024)
client-output-buffer-size Integer 131072 No No Client Network Output Buffer Size (min: 1024)
client-output-extend-size Integer 131072 No No Client Network Output Extend Size (min: 1024)
smqp-producer-reply-interval Integer 20 Yes No Number of SMQP Requests after which a SMQP Reply is required (min: 1)
smqp-consumer-cache-size Integer 500 Yes No Cache Size per Consumer (Messages) (min: 1)
smqp-consumer-cache-size-kb Integer 2048 Yes No Cache Size per Consumer (KB)
jms-client-id String No No JMS Client Id for durable Subscribers
jms-default-delivery-mode String persistent Yes No JMS Default Delivery Mode (choices: persistent, non_persistent)
jms-default-message-ttl Long 0 Yes No JMS Default Message TTL (min: 0)
jms-default-message-priority Integer 4 Yes No JMS Default Message Priority (range: 0–9)
jms-default-message-id-enabled Boolean true No No JMS Default Message Id Enabled
jms-default-message-timestamp-enabled Boolean true No No JMS Default Message Timestamp Enabled
thread-context-classloader-for-getobject Boolean false No No Use the Thread Context Classloader for getObject()
<swiftlet name="sys$jms">
  <listeners>
    <listener name="...">
      <connection-factories>
        <connection-factory name="..." smqp-producer-reply-interval="..." smqp-consumer-cache-size="..." smqp-consumer-cache-size-kb="..." jms-default-delivery-mode="..." jms-default-message-ttl="..." jms-default-message-priority="..."/>
      </connection-factories>
    </listener>
  </listeners>
</swiftlet>