Chapter 4. Configuration
This chapter describes the process for binding the AMQ JMS implementation to your JMS application and setting configuration options.
JMS uses the Java Naming Directory Interface (JNDI) to register and look up API implementations and other resources. This enables you to write code to the JMS API without tying it to a particular implementation.
Configuration options are exposed as query parameters on the connection URI. Some of the options are also exposed as corresponding set
and get
methods on the ConnectionFactory
implementation object.
4.1. Configuring the initial context factory
JMS applications use a JNDI InitialContext
object obtained from an InitialContextFactory
to look up JMS objects such as the connection factory. AMQ JMS provides an implementation of the InitialContextFactory
in the org.apache.qpid.jms.jndi.JmsInitialContextFactory
class.
The InitialContextFactory
implementation is discovered when the InitialContext
object is instantiated:
javax.naming.Context context = new javax.naming.InitialContext();
To find an implementation, JNDI must be configured in your environment. There are two main ways of achieving this, using a jndi.properties
file or using a system property.
Using a jndi.properties file
Create a file named jndi.properties
and place it on the Java classpath. Add a property with the key java.naming.factory.initial
.
Example: Setting the JNDI initial context factory using a jndi.properties file
java.naming.factory.initial = org.apache.qpid.jms.jndi.JmsInitialContextFactory
In Maven-based projects, the jndi.properties
file is placed in the <project-dir>/src/main/resources
directory.
Using a system property
Set the java.naming.factory.initial
system property.
Example: Setting the JNDI initial context factory using a system property
$ java -Djava.naming.factory.initial=org.apache.qpid.jms.jndi.JmsInitialContextFactory ...
4.2. Configuring the connection factory
The JMS connection factory is the entry point for creating connections. It uses a connection URI that encodes your application-specific configuration settings.
To set the factory name and connection URI, create a property in the format below. You can store this configuration in a jndi.properties
file or set the corresponding system property.
The JNDI property format for connection factories
connectionFactory.<factory-name> = <connection-uri>
For example, this is how you might configure a factory named app1
:
Example: Setting the connection factory in a jndi.properties file
connectionFactory.app1 = amqp://example.net:5672?jms.clientID=backend
You can then use the JNDI context to look up your configured connection factory using the name app1
:
ConnectionFactory factory = (ConnectionFactory) context.lookup("app1");
4.3. Connection URIs
A connection factory is configured using a connection URI in the following format:
The connection URI format
amqp[s]://<host>:<port>[?<option>=<value>[&<option>=<value>...]]
For example, the following is a connection URI that connects to host example.net
at port 5672
and sets the client ID to backend
:
Example: A connection URI
amqp://example.net:5672?jms.clientID=backend
The available connection options are described in the sections following this one.
When failover is configured, the client can reconnect to another server automatically if the connection to the current server is lost. Failover URIs have the prefix failover:
and contain a comma-separated list of server URIs inside parentheses. Additional options are specified at the end.
The failover URI format
failover:(amqp[s]://<host>:<port>[,amqp[s]://<host>:<port>...])[?<option>=<value>[&<option>=<value>...]]
As with the connection URI example, the client can be configured with a number of different settings using the URI in a failover configuration. These settings are detailed below, with the Section 4.8, “Failover options” section being of particular interest.
When the amqps
scheme is used to specify an SSL/TLS connection, the hostname segment from the URI can be used by the JVM’s TLS SNI (Server Name Indication) extension to communicate the desired server hostname during a TLS handshake. The SNI extension is automatically included if a Fully Qualified Domain Name (for example, "myhost.mydomain") is specified, but not when an unqualified name (for example, "myhost") or a bare IP address is used.
4.4. JMS options
These options control the behaviour of JMS objects such as Connection
, Session
, MessageConsumer
, and MessageProducer
.
- jms.username
- The user name used to authenticate the connection.
- jms.password
- The password used to authenticate the connection.
- jms.clientID
- The client ID that is applied to the connection.
- jms.forceAsyncSend
-
If enabled, all messages from a
MessageProducer
are sent asynchronously. Otherwise, only certain kinds, such as non-persistent messages or those inside a transaction, are sent asynchronously. It is disabled by default. - jms.forceSyncSend
-
If enabled, all messages from a
MessageProducer
are sent synchronously. It is disabled by default. - jms.forceAsyncAcks
- If enabled, all message acknowledgments are sent asynchronously. It is disabled by default.
- jms.localMessageExpiry
-
If enabled, any expired messages received by a
MessageConsumer
are filtered out and not delivered. It is enabled by default. - jms.localMessagePriority
- If enabled, prefetched messages are reordered locally based on their message priority value. It is disabled by default.
- jms.validatePropertyNames
- If enabled, message property names are required to be valid Java identifiers. It is enabled by default.
- jms.receiveLocalOnly
-
If enabled, calls to
receive
with a timeout argument will check a consumer’s local message buffer only. Otherwise, if the timeout expires, the remote peer is checked to ensure there are really no messages. It is disabled by default. - jms.receiveNoWaitLocalOnly
-
If enabled, calls to
receiveNoWait
will check a consumer’s local message buffer only. Otherwise, the remote peer is checked to ensure there are really no messages available. It is disabled by default. - jms.queuePrefix
-
An optional prefix value added to the name of any
Queue
created from aSession
. - jms.topicPrefix
-
An optional prefix value added to the name of any
Topic
created from aSession
. - jms.closeTimeout
- The time in milliseconds for which the client will wait for normal resource closure before returning. The default is 60000 (60 seconds).
- jms.connectTimeout
- The time in milliseconds for which the client will wait for connection establishment before returning with an error. The default is 15000 (15 seconds).
- jms.sendTimeout
- The time in milliseconds for which the client will wait for completion of a synchronous message send before returning an error. By default the client will wait indefinitely for a send to complete.
- jms.requestTimeout
- The time in milliseconds for which the client will wait for completion of various synchronous interactions like opening a producer or consumer (excluding send) with the remote peer before returning an error. By default the client will wait indefinitely for a request to complete.
- jms.clientIDPrefix
-
An optional prefix value used to generate client ID values when a new
Connection
is created by theConnectionFactory
. The default isID:
. - jms.connectionIDPrefix
-
An optional prefix value used to generate connection ID values when a new
Connection
is created by theConnectionFactory
. This connection ID is used when logging some information from theConnection
object, so a configurable prefix can make breadcrumbing the logs easier. The default isID:
. - jms.populateJMSXUserID
-
If enabled, populate the
JMSXUserID
property for each sent message using the authenticated user name from the connection. It is disabled by default. - jms.awaitClientID
- If enabled, a connection with no client ID configured in the URI will wait for a client ID to be set programmatically, or the connection being used otherwise to signal none can be set, before sending the AMQP connection "open". It is enabled by default.
- jms.useDaemonThread
- If enabled, a connection will use a daemon thread for its executor, rather than a non-daemon thread. It is disabled by default.
- jms.tracing
-
The name of a tracing provider. Supported values are
opentracing
andnoop
. The default isnoop
.
Prefetch policy options
Prefetch policy determines how many messages each MessageConsumer
will fetch from the remote peer and hold in a local "prefetch" buffer.
- jms.prefetchPolicy.queuePrefetch
- The default is 1000.
- jms.prefetchPolicy.topicPrefetch
- The default is 1000.
- jms.prefetchPolicy.queueBrowserPrefetch
- The default is 1000.
- jms.prefetchPolicy.durableTopicPrefetch
- The default is 1000.
- jms.prefetchPolicy.all
- This can be used to set all prefetch values at once.
The value of prefetch can affect the distribution of messages to multiple consumers on a queue or shared subscription. A higher value can result in larger batches sent at once to each consumer. To achieve more even round-robin distribution, use a lower value.
Redelivery policy options
Redelivery policy controls how redelivered messages are handled on the client.
- jms.redeliveryPolicy.maxRedeliveries
- Controls when an incoming message is rejected based on the number of times it has been redelivered. A value of 0 indicates that no message redeliveries are accepted. A value of 5 allows a message to be redelivered five times, and so on. The default is -1, meaning no limit.
- jms.redeliveryPolicy.outcome
-
Controls the outcome applied to a message once it has exceeded the configured maxRedeliveries value. Supported values are:
ACCEPTED
,REJECTED
,RELEASED
,MODIFIED_FAILED
andMODIFIED_FAILED_UNDELIVERABLE
. The default value isMODIFIED_FAILED_UNDELIVERABLE
.
Message ID policy options
Message ID policy controls the data type of the message ID assigned to messages sent from the client.
- jms.messageIDPolicy.messageIDType
-
By default, a generated
String
value is used for the message ID on outgoing messages. Other available types areUUID
,UUID_STRING
, andPREFIXED_UUID_STRING
.
Presettle policy options
Presettle policy controls when a producer or consumer instance will be configured to use AMQP presettled messaging semantics.
- jms.presettlePolicy.presettleAll
- If enabled, all producers and non-transacted consumers created operate in presettled mode. It is disabled by default.
- jms.presettlePolicy.presettleProducers
- If enabled, all producers operate in presettled mode. It is disabled by default.
- jms.presettlePolicy.presettleTopicProducers
-
If enabled, any producer that is sending to a
Topic
orTemporaryTopic
destination will operate in presettled mode. It is disabled by default. - jms.presettlePolicy.presettleQueueProducers
-
If enabled, any producer that is sending to a
Queue
orTemporaryQueue
destination will operate in presettled mode. It is disabled by default. - jms.presettlePolicy.presettleTransactedProducers
-
If enabled, any producer that is created in a transacted
Session
will operate in presettled mode. It is disabled by default. - jms.presettlePolicy.presettleConsumers
- If enabled, all consumers operate in presettled mode. It is disabled by default.
- jms.presettlePolicy.presettleTopicConsumers
-
If enabled, any consumer that is receiving from a
Topic
orTemporaryTopic
destination will operate in presettled mode. It is disabled by default. - jms.presettlePolicy.presettleQueueConsumers
-
If enabled, any consumer that is receiving from a
Queue
orTemporaryQueue
destination will operate in presettled mode. It is disabled by default.
Deserialization policy options
Deserialization policy provides a means of controlling which Java types are trusted to be deserialized from the object stream while retrieving the body from an incoming ObjectMessage
composed of serialized Java Object
content. By default all types are trusted during an attempt to deserialize the body. The default deserialization policy provides URI options that allow specifying a whitelist and a blacklist of Java class or package names.
- jms.deserializationPolicy.whiteList
-
A comma-separated list of class and package names that should be allowed when deserializing the contents of an
ObjectMessage
, unless overridden byblackList
. The names in this list are not pattern values. The exact class or package name must be configured, as injava.util.Map
orjava.util
. Package matches include sub-packages. The default is to allow all. - jms.deserializationPolicy.blackList
-
A comma-separated list of class and package names that should be rejected when deserializing the contents of a
ObjectMessage
. The names in this list are not pattern values. The exact class or package name must be configured, as injava.util.Map
orjava.util
. Package matches include sub-packages. The default is to prevent none.
4.5. TCP options
When connected to a remote server using plain TCP, the following options specify the behavior of the underlying socket. These options are appended to the connection URI along with any other configuration options.
Example: A connection URI with transport options
amqp://localhost:5672?jms.clientID=foo&transport.connectTimeout=30000
The complete set of TCP transport options is listed below.
- transport.sendBufferSize
- The send buffer size in bytes. The default is 65536 (64 KiB).
- transport.receiveBufferSize
- The receive buffer size in bytes. The default is 65536 (64 KiB).
- transport.trafficClass
- The default is 0.
- transport.connectTimeout
- The default is 60 seconds.
- transport.soTimeout
- The default is -1.
- transport.soLinger
- The default is -1.
- transport.tcpKeepAlive
- The default is false.
- transport.tcpNoDelay
- If enabled, do not delay and buffer TCP sends. It is enabled by default.
- transport.useEpoll
- When available, use the native epoll IO layer instead of the NIO layer. This can improve performance. It is enabled by default.
4.6. SSL/TLS options
The SSL/TLS transport is enabled by using the amqps
URI scheme. Because the SSL/TLS transport extends the functionality of the TCP-based transport, all of the TCP transport options are valid on an SSL/TLS transport URI.
Example: A simple SSL/TLS connection URI
amqps://myhost.mydomain:5671
The complete set of SSL/TLS transport options is listed below.
- transport.keyStoreLocation
-
The path to the SSL/TLS key store. If unset, the value of the
javax.net.ssl.keyStore
system property is used. - transport.keyStorePassword
-
The password for the SSL/TLS key store. If unset, the value of the
javax.net.ssl.keyStorePassword
system property is used. - transport.trustStoreLocation
-
The path to the SSL/TLS trust store. If unset, the value of the
javax.net.ssl.trustStore
system property is used. - transport.trustStorePassword
-
The password for the SSL/TLS trust store. If unset, the value of the
javax.net.ssl.trustStorePassword
system property is used. - transport.keyStoreType
-
If unset, the value of the
javax.net.ssl.keyStoreType
system property is used. If the system property is unset, the default isJKS
. - transport.trustStoreType
-
If unset, the value of the
javax.net.ssl.trustStoreType
system property is used. If the system property is unset, the default isJKS
. - transport.storeType
-
Sets both
keyStoreType
andtrustStoreType
to the same value. If unset,keyStoreType
andtrustStoreType
default to the values specified above. - transport.contextProtocol
-
The protocol argument used when getting an SSLContext. The default is
TLS
, orTLSv1.2
if using OpenSSL. - transport.enabledCipherSuites
- A comma-separated list of cipher suites to enable. If unset, the context-default ciphers are used. Any disabled ciphers are removed from this list.
- transport.disabledCipherSuites
- A comma-separated list of cipher suites to disable. Ciphers listed here are removed from the enabled ciphers.
- transport.enabledProtocols
- A comma-separated list of protocols to enable. If unset, the context-default protocols are used. Any disabled protocols are removed from this list.
- transport.disabledProtocols
-
A comma-separated list of protocols to disable. Protocols listed here are removed from the enabled protocol list. The default is
SSLv2Hello,SSLv3
. - transport.trustAll
- If enabled, trust the provided server certificate implicitly, regardless of any configured trust store. It is disabled by default.
- transport.verifyHost
- If enabled, verify that the connection hostname matches the provided server certificate. It is enabled by default.
- transport.keyAlias
- The alias to use when selecting a key pair from the key store if required to send a client certificate to the server.
- transport.useOpenSSL
If enabled, use native OpenSSL libraries for SSL/TLS connections if available. It is disabled by default.
For more information, see Section 6.2, “Enabling OpenSSL support”.
4.7. AMQP options
The following options apply to aspects of behavior related to the AMQP wire protocol.
- amqp.idleTimeout
- The time in milliseconds after which the connection is failed if the peer sends no AMQP frames. The default is 60000 (1 minute).
- amqp.vhost
- The virtual host to connect to. This is used to populate the SASL and AMQP hostname fields. The default is the main hostname from the connection URI.
- amqp.saslLayer
- If enabled, SASL is used when establishing connections. It is enabled by default.
- amqp.saslMechanisms
- A comma-separated list of SASL mechanisms the client should allow selection of, if offered by the server and usable with the configured credentials. The supported mechanisms are EXTERNAL, SCRAM-SHA-256, SCRAM-SHA-1, CRAM-MD5, PLAIN, ANONYMOUS, and GSSAPI for Kerberos. The default is to allow selection from all mechanisms except GSSAPI, which must be explicitly included here to enable.
- amqp.maxFrameSize
- The maximum AMQP frame size in bytes allowed by the client. This value will be advertised to the remote peer. The default is 1048576 (1 MiB).
- amqp.drainTimeout
- The time in milliseconds that the client will wait for a response from the remote peer when a consumer drain request is made. If no response is seen in the allotted timeout period, the link will be considered failed and the associated consumer will be closed. The default is 60000 (1 minute).
- amqp.allowNonSecureRedirects
- If enabled, allow AMQP redirects to alternative hosts when the existing connection is secure and the alternative connection is not. For example, if enabled this would permit redirecting an SSL/TLS connection to a raw TCP connection. It is disabled by default.
4.8. Failover options
Failover URIs start with the prefix failover:
and contain a comma-separated list of server URIs inside parentheses. Additional options are specified at the end. Options prefixed with jms.
are applied to the overall failover URI, outside of parentheses, and affect the Connection
object for its lifetime.
Example: A failover URI with failover options
failover:(amqp://host1:5672,amqp://host2:5672)?jms.clientID=foo&failover.maxReconnectAttempts=20
The individual broker details within the parentheses can use the transport.
or amqp.
options defined earlier. These are applied as each host is connected to.
Example: A failover URI with per-connection transport and AMQP options
failover:(amqp://host1:5672?amqp.option=value,amqp://host2:5672?transport.option=value)?jms.clientID=foo
All of the configuration options for failover are listed below.
- failover.initialReconnectDelay
- The time in milliseconds the client will wait before the first attempt to reconnect to a remote peer. The default is 0, meaning the first attempt happens immediately.
- failover.reconnectDelay
- The time in milliseconds between reconnection attempts. If the backoff option is not enabled, this value remains constant. The default is 10.
- failover.maxReconnectDelay
- The maximum time that the client will wait before attempting to reconnect. This value is only used when the backoff feature is enabled to ensure that the delay does not grow too large. The default is 30 seconds.
- failover.useReconnectBackOff
- If enabled, the time between reconnection attempts grows based on a configured multiplier. It is enabled by default.
- failover.reconnectBackOffMultiplier
- The multiplier used to grow the reconnection delay value. The default is 2.0.
- failover.maxReconnectAttempts
- The number of reconnection attempts allowed before reporting the connection as failed to the client. The default is -1, meaning no limit.
- failover.startupMaxReconnectAttempts
-
For a client that has never connected to a remote peer before, this option controls how many attempts are made to connect before reporting the connection as failed. If unset, the value of
maxReconnectAttempts
is used. - failover.warnAfterReconnectAttempts
- The number of failed reconnection attempts until a warning is logged. The default is 10.
- failover.randomize
- If enabled, the set of failover URIs is randomly shuffled before attempting to connect to one of them. This can help to distribute client connections more evenly across multiple remote peers. It is disabled by default.
- failover.amqpOpenServerListAction
-
Controls how the failover transport behaves when the connection "open" frame from the server provides a list of failover hosts to the client. Valid values are
REPLACE
,ADD
, orIGNORE
. IfREPLACE
is configured, all failover URIs other than the one for the current server are replaced with those provided by the server. IfADD
is configured, the URIs provided by the server are added to the existing set of failover URIs, with deduplication. IfIGNORE
is configured, any updates from the server are ignored and no changes are made to the set of failover URIs in use. The default isREPLACE
.
The failover URI also supports defining nested options as a means of specifying AMQP and transport option values applicable to all the individual nested broker URIs. This is accomplished using the same transport.
and amqp.
URI options outlined earlier for a non-failover broker URI but prefixed with failover.nested.
. For example, to apply the same value for the amqp.vhost
option to every broker connected to you might have a URI like the following:
Example: A failover URI with shared transport and AMQP options
failover:(amqp://host1:5672,amqp://host2:5672)?jms.clientID=foo&failover.nested.amqp.vhost=myhost
4.9. Discovery options
The client has an optional discovery module that provides a customized failover layer where the broker URIs to connect to are not given in the initial URI but instead are discovered by interacting with a discovery agent. There are currently two discovery agent implementations: a file watcher that loads URIs from a file and a multicast listener that works with ActiveMQ 5.x brokers that are configured to broadcast their broker addresses for listening clients.
The general set of failover-related options when using discovery are the same as those detailed earlier, with the main prefix changed from failover.
to discovery.
, and with the nested
prefix used to supply URI options common to all the discovered broker URIs. For example, without the agent URI details, a general discovery URI might look like the following:
Example: A discovery URI
discovery:(<agent-uri>)?discovery.maxReconnectAttempts=20&discovery.discovered.jms.clientID=foo
To use the file watcher discovery agent, create an agent URI like the following:
Example: A discovery URI using the file watcher agent
discovery:(file:///path/to/monitored-file?updateInterval=60000)
The URI options for the file watcher discovery agent are listed below.
- updateInterval
- The time in milliseconds between checks for file changes. The default is 30000 (30 seconds).
To use the multicast discovery agent with an ActiveMQ 5.x broker, create an agent URI like the following:
Example: A discovery URI using the multicast listener agent
discovery:(multicast://default?group=default)
Note that the use of default
as the host in the multicast agent URI above is a special value that is substituted by the agent with the default 239.255.2.3:6155
. You can change this to specify the actual IP address and port in use with your multicast configuration.
The URI option for the multicast discovery agent is listed below.
- group
-
The multicast group used to listen for updates. The default is
default
.
4.10. Configuring JNDI resources
4.10.1. Configuring queue and topic names
JMS provides the option of using JNDI to look up deployment-specific queue and topic resources.
To set queue and topic names in JNDI, create properties in the following format. Either place this configuration in a jndi.properties
file or define corresponding system properties.
The JNDI property format for queues and topics
queue.<queue-lookup-name> = <queue-name> topic.<topic-lookup-name> = <topic-name>
For example, the following properties define the names jobs
and notifications
for two deployment-specific resources:
Example: Setting queue and topic names in a jndi.properties file
queue.jobs = app1/work-items topic.notifications = app1/updates
You can then look up the resources by their JNDI names:
Queue queue = (Queue) context.lookup("jobs"); Topic topic = (Topic) context.lookup("notifications");
4.10.2. Setting JNDI properties programatically
As an alternative to using a jndi.properties
file or system properties to configure JNDI, you can define properties programatically using the JNDI initial context API.
Example: Setting JNDI properties programatically
Hashtable<Object, Object> env = new Hashtable<>(); env.put("java.naming.factory.initial", "org.apache.qpid.jms.jndi.JmsInitialContextFactory"); env.put("connectionFactory.app1", "amqp://example.net:5672?jms.clientID=backend"); env.put("queue.jobs", "app1/work-items"); env.put("topic.notifications", "app1/updates"); InitialContext context = new InitialContext(env);
4.10.3. Variable expansion in JNDI properties
JNDI property values can contain variables of the form ${<variable-name>}
. The library resolves the variable value by searching in order in the following locations:
- Java system properties
- OS environment variables
- The JNDI properties file or environment Hashtable
For example, on Linux ${HOME}
resolves to the HOME
environment variable, the current user’s home directory.
A default value can be supplied using the syntax ${<variable-name>:-<default-value>}
. If no value for <variable-name>
is found, the default value is used instead.