Chapter 4. Configuration
This section details various configuration options for the client, such as how to configure and create a JNDI InitialContext
, the syntax for its related configuration, and the URI options that can be set when defining a ConnectionFactory
.
4.1. Configuring a JNDI InitialContext
JMS applications use a JNDI InitialContext
obtained from an InitialContextFactory
to look up JMS objects such as ConnectionFactory
. The client provides an implementation of the InitialContextFactory
in the org.apache.qpid.jms.jndi.JmsInitialContextFactory
class. You can configure it three different ways.
Configuring an InitialContext Using a jndi.properties
File
If you include a file named jndi.properties
on the classpath and set the java.naming.factory.initial
property value to org.apache.qpid.jms.jndi.JmsInitialContextFactory
, the client InitialContextFactory
implementation is discovered when the InitialContext object
is instantiated.
javax.naming.Context ctx = new javax.naming.InitialContext();
The particular ConnectionFactory
, Queue
, and Topic
objects that you want the Context
to contain are configured as properties either directly within the jndi.properties
file or in a separate file whose path is referenced in jndi.properties
using the java.naming.provider.url
property. The syntax for these properties is detailed below.
Configuring an InitialContext Using System Properties
If you set the java.naming.factory.initial
system property to the value org.apache.qpid.jms.jndi.JmsInitialContextFactory
, the client InitialContextFactory
implementation is discovered when the InitialContext
object is instantiated.
javax.naming.Context ctx = new javax.naming.InitialContext();
The particular ConnectionFactory
, Queue
, and Topic
objects that you want the context to contain are configured as properties in a file, the path to which is passed using the java.naming.provider.url
system property. The syntax for these properties is detailed below.
Configuring an InitialContext Programmatically
You can configure the InitialContext
directly by setting an environment variable on a Hashtable
environment object.
Hashtable<Object, Object> env = new Hashtable<Object, Object>(); env.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.qpid.jms.jndi.JmsInitialContextFactory"); javax.naming.Context context = new javax.naming.InitialContext(env);
The particular ConnectionFactory
, Queue
, and Topic
objects that you want the context to contain are configured as properties (the syntax for which is detailed below) either directly within the environment Hashtable
or in a separate file whose path is referenced using the java.naming.provider.url
property within the environment Hashtable
.
JNDI Property Syntax
The property syntax used in the properties file or environment Hashtable is as follows:
-
To define a
ConnectionFactory
, use formatconnectionfactory.LOOKUP_NAME = CONNECTION_URI
. -
To define a
Queue
, use formatqueue.LOOKUP_NAME = QUEUE_NAME
. -
To define a
Topic
use formattopic.LOOKUP_NAME = TOPIC_NAME
.
For more details about the connection URI, see the next section.
As an example, consider the following properties that define a ConnectionFactory
, Queue
, and Topic
.
connectionfactory.myFactoryLookup = amqp://localhost:5672 queue.myQueueLookup = queueA topic.myTopicLookup = topicA
These objects could then be looked up from a Context
as follows.
ConnectionFactory factory = (ConnectionFactory) context.lookup("myFactoryLookup"); Queue queue = (Queue) context.lookup("myQueueLookup"); Topic topic = (Topic) context.lookup("myTopicLookup");
4.2. Connection URIs
A ConnectionFactory
is configured using a connection URI.
Connection URI Format
amqp[s]://host:port[?option=value[&option2=value...]]
The available connection settings are detailed in the Section 4.3, “Connection URI Options” section.
When failover is configured, the client can reconnect to another server automatically if the connection to the current server is lost. 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.
Failover URI Format
failover:(amqp://host1:port[,amqp://host2:port...])[?option=value[&option2=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.3.5, “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.3. Connection URI Options
4.3.1. JMS Options
These options control the behaviour of JMS objects such as Connection
, Session
, MessageConsumer
, and MessageProducer
.
- jms.username - The username 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. Default is false. -
jms.forceSyncSend - If enabled, all messages from a
MessageProducer
are sent synchronously. Default is false. - jms.forceAsyncAcks - If enabled, all message acknowledgments are sent asynchronously. Default is false.
-
jms.localMessageExpiry - If enabled, any expired messages received by a
MessageConsumer
are filtered out and not delivered. Default is true. - jms.localMessagePriority - If enabled, prefetched messages are reordered locally based on their message priority value. Default is false.
- jms.validatePropertyNames - If enabled, message property names are required to be valid Java identifiers. Default is true.
-
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. Default is false. -
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. Default is false. -
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. 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. 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
. 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. Default isID:
. -
jms.populateJMSXUserID - If enabled, populate the
JMSXUserID
property for each sent message using the authenticated username from the connection. Default is false. - jms.awaitClientID - If enabled, a connection with no ClientID configured in the URI will wait for a ClientID to be set programmatically, or the connection being used otherwise to signal none can be set, before sending the AMQP connection Open. Default is true.
- jms.useDaemonThread - If enabled, a connection will use a daemon thread for its executor, rather than a non-daemon thread. Default is false.
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 - Default is 1000.
- jms.prefetchPolicy.topicPrefetch - Default is 1000.
- jms.prefetchPolicy.queueBrowserPrefetch - Default is 1000.
- jms.prefetchPolicy.durableTopicPrefetch - Default is 1000.
- jms.prefetchPolicy.all - Used to set all prefetch values at once.
The value of prefetch affects the distribution of messages to multiple consumers on a queue. A higher value results 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. Default is -1, meaning no limit.
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. Default is false.
- jms.presettlePolicy.presettleProducers - If enabled, all producers operate in presettled mode. Default is false.
-
jms.presettlePolicy.presettleTopicProducers - If enabled, any producer that is sending to a
Topic
orTemporaryTopic
destination will operate in presettled mode. Default is false. -
jms.presettlePolicy.presettleQueueProducers - If enabled, any producer that is sending to a
Queue
orTemporaryQueue
destination will operate in presettled mode. Default is false. -
jms.presettlePolicy.presettleTransactedProducers - If enabled, any producer that is created in a transacted
Session
will operate in presettled mode. Default is false. - jms.presettlePolicy.presettleConsumers - If enabled, all consumers operate in presettled mode. Default is false.
-
jms.presettlePolicy.presettleTopicConsumers - If enabled, any consumer that is receiving from a
Topic
orTemporaryTopic
destination will operate in presettled mode. Default is false. -
jms.presettlePolicy.presettleQueueConsumers - If enabled, any consumer that is receiving from a
Queue
orTemporaryQueue
destination will operate in presettled mode. Default is false.
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. 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. Default is to prevent none.
4.3.2. TCP Transport 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 - Default is 64k.
- transport.receiveBufferSize - Default is 64k.
- transport.trafficClass - Default is 0.
- transport.connectTimeout - Default is 60 seconds.
- transport.soTimeout - Default is -1.
- transport.soLinger - Default is -1.
- transport.tcpKeepAlive - Default is false.
- transport.tcpNoDelay - Default is true.
- transport.useEpoll - When available, use the native epoll IO layer instead of the NIO layer. This can improve performance. Default is true.
4.3.3. SSL/TLS Transport 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 - Default is to read from the system property
javax.net.ssl.keyStore
. -
transport.keyStorePassword - Default is to read from the system property
javax.net.ssl.keyStorePassword
. -
transport.trustStoreLocation - Default is to read from the system property
javax.net.ssl.trustStore
. -
transport.trustStorePassword - Default is to read from the system property
javax.net.ssl.trustStorePassword
. -
transport.keyStoreType - The type of key store being used. Default is to read from the system property
javax.net.ssl.keyStoreType
. If the property is not set, the default isJKS
. -
transport.trustStoreType - The type of trust store being used. Default is to read from the system property
javax.net.ssl.trustStoreType
. If the property is not set, the default isJKS
. -
transport.storeType - Sets both
keyStoreType
andtrustStoreType
to the same value. If not set,keyStoreType
andtrustStoreType
will default to the values specified above. -
transport.contextProtocol - The protocol argument used when getting an SSLContext. Default is
TLS
. - transport.enabledCipherSuites - A comma-separated list of cipher suites to enable. No default, meaning the context default ciphers are used. Any disabled ciphers are removed from this list.
- transport.disabledCipherSuites - A comma-separated list cipher suites to disable. Ciphers listed here are removed from the enabled ciphers. No default.
- transport.enabledProtocols - A comma-separated list of protocols to enable. No default, meaning 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. Default is
SSLv2Hello,SSLv3
. - transport.trustAll - If enabled, trust the provided server certificate implicitly, regardless of any configured trust store. Default is false.
- transport.verifyHost - If enabled, verify that the connection hostname matches the provided server certificate. Default is true.
- 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. No default.
4.3.4. 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 will be failed if the peer sends no AMQP frames. Default is 60000 (1 minute).
- amqp.vhost - The virtual host to connect to. Used to populate the SASL and AMQP hostname fields. Default is the main hostname from the connection URI.
- amqp.saslLayer - If enabled, SASL is used when establishing connections. Default is true.
- 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. 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. 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. Default is 60000 (1 minute).
- amqp.allowNonSecureRedirects - Controls whether the client allows an AMQP redirect to an alternative host over a connection that is not secure when the existing connection is secure, such as redirecting an SSL/TLS connection to a raw TCP connection. Default is false.
4.3.5. 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. 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. 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. Default is 30 seconds.
- failover.useReconnectBackOff - If enabled, the time between reconnection attempts grows based on a configured multiplier. Default is true.
- failover.reconnectBackOffMultiplier - The multiplier used to grow the reconnection delay value. Default is 2.0.
- failover.maxReconnectAttempts - The number of reconnection attempts allowed before reporting the connection as failed to the client. 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. Default is to use the value of
maxReconnectAttempts
. - failover.warnAfterReconnectAttempts - Controls how often the client will log a message indicating that failover reconnection is being attempted. Default is to log every 10 connection attempts.
- 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. Default is false.
-
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. 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.3.6. 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. 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. Default is
default
.
4.4. Security
AMQ JMS has a range of security-related configuration options that can be leveraged according to your application’s needs.
Basic user credentials such as username and password should be passed directly to the ConnectionFactory
when creating the Connection
within the application. However, if you are using the no-argument factory method, it is also possible to supply user credentials in the connection URI. For more information, see the Section 4.3.1, “JMS Options” section.
Another common security consideration is use of SSL/TLS. The client connects to servers over an SSL/TLS transport when the amqps
URI scheme is specified in the connection URI, with various options available to configure behavior. For more information, see the Section 4.3.3, “SSL/TLS Transport Options” section.
In concert with the earlier items, it may be desirable to restrict the client to allow use of only particular SASL mechanisms from those that may be offered by a server, rather than selecting from all it supports. For more information, see the Section 4.3.4, “AMQP Options” section.
Applications calling getObject()
on a received ObjectMessage
may wish to restrict the types created during deserialization. Note that message bodies composed using the AMQP type system do not use the ObjectInputStream
mechanism and therefore do not require this precaution. For more information, see the the section called “Deserialization Policy Options” section.
4.4.1. Authenticating Using Kerberos
The client can be configured to authenticate using Kerberos when used with an appropriately configured server. To enable Kerberos, use the following steps.
Configure the client to use the
GSSAPI
mechanism for SASL authentication using theamqp.saslMechanisms
URI option.amqp://myhost:5672?amqp.saslMechanisms=GSSAPI failover:(amqp://myhost:5672?amqp.saslMechanisms=GSSAPI)
Set the
java.security.auth.login.config
system property to the path of a JAAS login configuration file containing appropriate configuration for a KerberosLoginModule
.-Djava.security.auth.login.config=LOGIN_CONFIG_FILE
The login configuration file might look like the following example.
amqp-jms-client { com.sun.security.auth.module.Krb5LoginModule required useTicketCache=true; };
The precise configuration used will depend on how you wish the credentials to be established for the connection, and the particular LoginModule
in use. For details of the Oracle Krb5LoginModule
, see the Oracle Krb5LoginModule
class reference. For details of the IBM Java 8 Krb5LoginModule
, see the IBM Krb5LoginModule
class reference.
It is possible to configure a LoginModule
to establish the credentials to use for the Kerberos process, such as specifying a principal and whether to use an existing ticket cache or keytab. If, however, the LoginModule
configuration does not provide the means to establish all necessary credentials, it may then request and be passed the username and password values from the client Connection
object if they were either supplied when creating the Connection
using the ConnectionFactory
or previously configured via its URI options.
Note that Kerberos is supported only for authentication purposes. Use SSL/TLS connections for encryption.
The following connection URI options can be used to influence the Kerberos authentication process.
-
sasl.options.configScope - The name of the login configuration entry used to authenticate. Default is
amqp-jms-client
. -
sasl.options.protocol - The protocol value used during the GSSAPI SASL process. Default is
amqp
. -
sasl.options.serverName - The
serverName
value used during the GSSAPI SASL process. Default is the server hostname from the connection URI.
Similar to the amqp.
and transport.
options detailed previously, these options must be specified on a per-host basis or as all-host nested options in a failover URI.
4.5. Logging
The client uses the SLF4J API, enabling users to select a particular logging implementation based on their needs by supplying an SLF4J binding, such as slf4j-log4j, in order to use Log4J. More details on SLF4J are available from its website.
The client uses Logger
names residing within the org.apache.qpid.jms
hierarchy, which you can use to configure a logging implementation based on your needs.
When debugging, it is sometimes useful to enable additional protocol trace logging from the Qpid Proton AMQP 1.0 library. There are two ways to achieve this.
-
Set the environment variable (not the Java system property)
PN_TRACE_FRM
to1
. This will cause Proton to emit frame logging to the console. -
Add the option
amqp.traceFrames=true
to your connection URI and configure theorg.apache.qpid.jms.provider.amqp.FRAMES
logger to log levelTRACE
. This will add a protocol tracer to Proton and include the output in your logs.
You can also configure the client to emit low-level tracing of input and output bytes. To enable this, add the option transport.traceBytes=true
to your connection URI and configure the org.apache.qpid.jms.transports.netty.NettyTcpTransport
logger to log level DEBUG
.
4.6. Extended Session Acknowledgment Modes
The client supports two additional session acknowledgement modes beyond those defined in the JMS specification.
Individual Acknowledge
In this mode, messages must be acknowledged individually by the application using the Message.acknowledge()
method when the session is in CLIENT_ACKNOWLEDGE
mode. Unlike with CLIENT_ACKNOWLEDGE
mode, only the target message is acknowledged. All other delivered messages remain unacknowledged. The integer value used to activate this mode is 101.
connection.createSession(false, 101);
No Acknowledge
In this mode, messages are accepted at the server before being dispatched to the client, and no acknowledgment is performed by the client. The client supports two integer values to activate this mode, 100 and 257.
connection.createSession(false, 100);