blob: 229610d155f0bebca79bf036662bffede8caf9c4 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.18">
<link rel="icon" type="image/png" href="images/favicon.png">
<title>Using JMS or Jakarta Messaging</title>
<link rel="stylesheet" href="css/asciidoctor.css">
<link rel="stylesheet" href="css/font-awesome.css">
<link rel="stylesheet" href="css/rouge-github.css">
</head>
<body class="book toc2 toc-left">
<div id="header">
<h1>Using JMS or Jakarta Messaging</h1>
<div id="toc" class="toc2">
<div id="toctitle"><a href="index.html">User Manual for 2.33.0</a></div>
<ul class="sectlevel1">
<li><a href="#a-simple-ordering-system">1. A simple ordering system</a></li>
<li><a href="#jndi">2. JNDI</a>
<ul class="sectlevel2">
<li><a href="#connectionfactory-jndi">2.1. ConnectionFactory JNDI</a></li>
<li><a href="#destination-jndi">2.2. Destination JNDI</a></li>
<li><a href="#the-code">2.3. The code</a></li>
</ul>
</li>
<li><a href="#directly-instantiating-jms-resources-without-using-jndi">3. Directly instantiating JMS Resources without using JNDI</a></li>
<li><a href="#setting-the-client-id">4. Setting The Client ID</a></li>
<li><a href="#setting-the-batch-size-for-dups_ok">5. Setting The Batch Size for DUPS_OK</a></li>
<li><a href="#setting-the-transaction-batch-size">6. Setting The Transaction Batch Size</a></li>
<li><a href="#setting-the-destination-cache">7. Setting The Destination Cache</a></li>
</ul>
</div>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Although Apache ActiveMQ Artemis provides a JMS agnostic messaging API, many users will be more comfortable using JMS.</p>
</div>
<div class="paragraph">
<p>JMS is a very popular API standard for messaging, and most messaging systems provide a JMS API.
If you are completely new to JMS we suggest you follow the <a href="https://docs.oracle.com/javaee/7/tutorial/partmessaging.htm">Oracle JMS tutorial</a> - a full JMS tutorial is out of scope for this guide.</p>
</div>
<div class="paragraph">
<p>Apache ActiveMQ Artemis also ships with a wide range of examples, many of which demonstrate JMS API usage.
A good place to start would be to play around with the simple JMS Queue and Topic example, but we also provide examples for many other parts of the JMS API.
A full description of the examples is available in <a href="examples.html#examples">Examples</a>.</p>
</div>
<div class="paragraph">
<p>In this section we&#8217;ll go through the main steps in configuring the server for JMS and creating a simple JMS program.
We&#8217;ll also show how to configure and use JNDI, and also how to use JMS with Apache ActiveMQ Artemis without using any JNDI.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="a-simple-ordering-system"><a class="anchor" href="#a-simple-ordering-system"></a><a class="link" href="#a-simple-ordering-system">1. A simple ordering system</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>For this chapter we&#8217;re going to use a very simple ordering system as our example.
It is a somewhat contrived example because of its extreme simplicity, but it serves to demonstrate the very basics of setting up and using JMS.</p>
</div>
<div class="paragraph">
<p>We will have a single JMS Queue called <code>OrderQueue</code>, and we will have a single <code>MessageProducer</code> sending an order message to the queue and a single <code>MessageConsumer</code> consuming the order message from the queue.</p>
</div>
<div class="paragraph">
<p>The queue will be a <code>durable</code> queue, i.e. it will survive a server restart or crash.
We also want to pre-deploy the queue, i.e. specify the queue in the server configuration so it is created automatically without us having to explicitly create it from the client.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="jndi"><a class="anchor" href="#jndi"></a><a class="link" href="#jndi">2. JNDI</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>The JMS specification establishes the convention that <em>administered objects</em> (i.e. JMS queue, topic and connection factory instances) are made available via the JNDI API.
Brokers are free to implement JNDI as they see fit assuming the implementation fits the API.
Apache ActiveMQ Artemis does not have a JNDI server.
Rather, it uses a client-side JNDI implementation that relies on special properties set in the environment to construct the appropriate JMS objects.
In other words, no objects are stored in JNDI on the Apache ActiveMQ Artemis server, instead they are simply instantiated on the client based on the provided configuration.
Let&#8217;s look at the different kinds of administered objects and how to configure them.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>The following configuration properties <em>are strictly required when Apache ActiveMQ Artemis is running in stand-alone mode</em>.
When Apache ActiveMQ Artemis is integrated to an application server (e.g. Wildfly) the application server itself will almost certainly provide a JNDI client with its own properties.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="sect2">
<h3 id="connectionfactory-jndi"><a class="anchor" href="#connectionfactory-jndi"></a><a class="link" href="#connectionfactory-jndi">2.1. ConnectionFactory JNDI</a></h3>
<div class="paragraph">
<p>A JMS connection factory is used by the client to make connections to the server.
It knows the location of the server it is connecting to, as well as many other configuration parameters.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s a simple example of the JNDI context environment for a client looking up a connection factory to access an <em>embedded</em> instance of Apache ActiveMQ Artemis:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight nowrap"><code data-lang="properties"><span class="py">java.naming.factory.initial</span><span class="p">=</span><span class="s">org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory</span>
<span class="py">connectionFactory.invmConnectionFactory</span><span class="p">=</span><span class="s">vm://0</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>In this instance we have created a connection factory that is bound to <code>invmConnectionFactory</code>, any entry with prefix <code>connectionFactory.</code> will create a connection factory.</p>
</div>
<div class="paragraph">
<p>In certain situations there could be multiple server instances running within a particular JVM.
In that situation each server would typically have an InVM acceptor with a unique server-ID.
A client using JMS and JNDI can account for this by specifying a connction factory for each server, like so:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight nowrap"><code data-lang="properties"><span class="py">java.naming.factory.initial</span><span class="p">=</span><span class="s">org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory</span>
<span class="py">connectionFactory.invmConnectionFactory0</span><span class="p">=</span><span class="s">vm://0</span>
<span class="py">connectionFactory.invmConnectionFactory1</span><span class="p">=</span><span class="s">vm://1</span>
<span class="py">connectionFactory.invmConnectionFactory2</span><span class="p">=</span><span class="s">vm://2</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Here is a list of all the supported URL schemes:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>vm</code></p>
</li>
<li>
<p><code>tcp</code></p>
</li>
<li>
<p><code>udp</code></p>
</li>
<li>
<p><code>jgroups</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Most clients won&#8217;t be connecting to an embedded broker.
Clients will most commonly connect across a network a remote broker.
Here&#8217;s a simple example of a client configuring a connection factory to connect to a remote broker running on myhost:5445:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight nowrap"><code data-lang="properties"><span class="py">java.naming.factory.initial</span><span class="p">=</span><span class="s">org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory</span>
<span class="py">connectionFactory.ConnectionFactory</span><span class="p">=</span><span class="s">tcp://myhost:5445</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>In the example above the client is using the <code>tcp</code> scheme for the provider URL.
A client may also specify multiple comma-delimited host:port combinations in the URL (e.g. <code>(tcp://remote-host1:5445,remote-host2:5445)</code>).
Whether there is one or many host:port combinations in the URL they are treated as the <em>initial connector(s)</em> for the underlying connection.</p>
</div>
<div class="paragraph">
<p>The <code>udp</code> scheme is also supported which should use a host:port combination that matches the <code>group-address</code> and <code>group-port</code> from the corresponding <code>broadcast-group</code> configured on the ActiveMQ Artemis server(s).</p>
</div>
<div class="paragraph">
<p>Each scheme has a specific set of properties which can be set using the traditional URL query string format (e.g. <code>scheme://host:port?key1=value1&amp;key2=value2</code>) to customize the underlying transport mechanism.
For example, if a client wanted to connect to a remote server using TCP and SSL it would create a connection factory like so, <code>tcp://remote-host:5445?ssl-enabled=true</code>.</p>
</div>
<div class="paragraph">
<p>All the properties available for the <code>tcp</code> scheme are described in <a href="configuring-transports.html#configuring-the-netty-transport">the documentation regarding the Netty transport</a>.</p>
</div>
<div class="paragraph">
<p>Note if you are using the <code>tcp</code> scheme and multiple addresses then a query can be applied to all the url&#8217;s or just to an individual connector, so where you have</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>(tcp://remote-host1:5445?httpEnabled=true,remote-host2:5445?httpEnabled=true)?clientID=1234</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>then the <code>httpEnabled</code> property is only set on the individual connectors where as the <code>clientId</code> is set on the actual connection factory.
Any connector specific properties set on the whole URI will be applied to all the connectors.</p>
</div>
<div class="paragraph">
<p>The <code>udp</code> scheme supports 4 properties:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">localAddress</dt>
<dd>
<p>If you are running with multiple network interfaces on the same machine, you may want to specify that the discovery group listens only on a specific interface.
To do this you can specify the interface address with this parameter.</p>
</dd>
<dt class="hdlist1">localPort</dt>
<dd>
<p>If you want to specify a local port to which the datagram socket is bound you can specify it here.
Normally you would just use the default value of -1 which signifies that an anonymous port should be used.
This parameter is always specified in conjunction with <code>localAddress</code>.</p>
</dd>
<dt class="hdlist1">refreshTimeout</dt>
<dd>
<p>This is the period the discovery group waits after receiving the last broadcast from a particular server before removing that servers connector pair entry from its list.
You would normally set this to a value significantly higher than the broadcast-period on the broadcast group otherwise servers might intermittently disappear from the list even though they are still broadcasting due to slight differences in timing.
This parameter is optional, the default value is 10000 milliseconds (10 seconds).</p>
</dd>
<dt class="hdlist1">discoveryInitialWaitTimeout</dt>
<dd>
<p>If the connection factory is used immediately after creation then it may not have had enough time to received broadcasts from all the nodes in the cluster.
On first usage, the connection factory will make sure it waits this long since creation before creating the first connection.
The default value for this parameter is 10000 milliseconds.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>Lastly, the <code>jgroups</code> scheme is supported which provides an alternative to the <code>udp</code> scheme for server discovery.
The URL pattern is <code>jgroups://channelName?file=jgroups-xml-conf-filename</code> where<code>jgroups-xml-conf-filename</code> refers to an XML file on the classpath that contains the JGroups configuration.
The <code>channelName</code> is the name given to the jgroups channel created.</p>
</div>
<div class="paragraph">
<p>The <code>refreshTimeout</code> and <code>discoveryInitialWaitTimeout</code> properties are supported just like with <code>udp</code>.</p>
</div>
<div class="paragraph">
<p>The default type for the default connection factory is of type <code>javax.jms.ConnectionFactory</code>or <code>jakarta.jms.ConnectionFactory</code> depending on the client you&#8217;re using.
This can be changed by setting the type like so</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight nowrap"><code data-lang="properties"><span class="py">java.naming.factory.initial</span><span class="p">=</span><span class="s">org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory</span>
<span class="py">java.naming.provider.url</span><span class="p">=</span><span class="s">tcp://localhost:5445?type=CF</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>In this example it is still set to the default, below shows a list of types that can be set.</p>
</div>
<div class="sect3">
<h4 id="configuration-for-connection-factory-types"><a class="anchor" href="#configuration-for-connection-factory-types"></a><a class="link" href="#configuration-for-connection-factory-types">2.1.1. Configuration for Connection Factory Types</a></h4>
<div class="paragraph">
<p>The interface provided will depend on whether you&#8217;re using the JMS or Jakarta Messaging client implementation.</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">type</th>
<th class="tableblock halign-left valign-top">interface</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">CF (default)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>javax.jms.ConnectionFactory</code> or <code>jakarta.jms.ConnectionFactory</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">XA_CF</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>javax.jms.XAConnectionFactory</code>or <code>jakarta.jms.XAConnectionFactory</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">QUEUE_CF</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>javax.jms.QueueConnectionFactory</code>or <code>jakarta.jms.QueueConnectionFactory</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">QUEUE_XA_CF</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>javax.jms.XAQueueConnectionFactory</code>or <code>jakarta.jms.XAQueueConnectionFactory</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">TOPIC_CF</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>javax.jms.TopicConnectionFactory</code>or <code>jakarta.jms.TopicConnectionFactory</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">TOPIC_XA_CF</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>javax.jms.XATopicConnectionFactory</code>or <code>jakarta.jms.XATopicConnectionFactory</code></p></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="destination-jndi"><a class="anchor" href="#destination-jndi"></a><a class="link" href="#destination-jndi">2.2. Destination JNDI</a></h3>
<div class="paragraph">
<p>JMS destinations are also typically looked up via JNDI.
As with connection factories, destinations can be configured using special properties in the JNDI context environment.
The property <em>name</em> should follow the pattern: <code>queue.&lt;jndi-binding&gt;</code> or <code>topic.&lt;jndi-binding&gt;</code>.
The property <em>value</em> should be the name of the queue hosted by the Apache ActiveMQ Artemis server.
For example, if the server had a JMS queue configured like so:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight nowrap"><code data-lang="xml"><span class="nt">&lt;address</span> <span class="na">name=</span><span class="s">"OrderQueue"</span><span class="nt">&gt;</span>
<span class="nt">&lt;queue</span> <span class="na">name=</span><span class="s">"OrderQueue"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/address&gt;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>And if the client wanted to bind this queue to "queues/OrderQueue" then the JNDI properties would be configured like so:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight nowrap"><code data-lang="properties"><span class="py">java.naming.factory.initial</span><span class="p">=</span><span class="s">org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory</span>
<span class="py">java.naming.provider.url</span><span class="p">=</span><span class="s">tcp://myhost:5445</span>
<span class="err">queue.queues/</span><span class="py">OrderQueue</span><span class="p">=</span><span class="s">OrderQueue</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>It is also possible to look-up JMS destinations which haven&#8217;t been configured explicitly in the JNDI context environment.
This is possible using <code>dynamicQueues/</code> or <code>dynamicTopics/</code> in the look-up string.
For example, if the client wanted to look-up the aforementioned "OrderQueue" it could do so simply by using the string "dynamicQueues/OrderQueue".
Note, the text that follows <code>dynamicQueues/</code> or <code>dynamicTopics/</code> must correspond <em>exactly</em> to the name of the destination on the server.</p>
</div>
</div>
<div class="sect2">
<h3 id="the-code"><a class="anchor" href="#the-code"></a><a class="link" href="#the-code">2.3. The code</a></h3>
<div class="paragraph">
<p>Here&#8217;s the code for the example:</p>
</div>
<div class="paragraph">
<p>First we&#8217;ll create a JNDI initial context from which to lookup our JMS objects.
If the above properties are set in <code>jndi.properties</code> and it is on the classpath then any new, empty <code>InitialContext</code> will be initialized using those properties:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight nowrap"><code data-lang="java"><span class="nc">InitialContext</span> <span class="n">ic</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">InitialContext</span><span class="o">();</span>
<span class="c1">//Now we'll look up the connection factory from which we can create</span>
<span class="c1">//connections to myhost:5445:</span>
<span class="nc">ConnectionFactory</span> <span class="n">cf</span> <span class="o">=</span> <span class="o">(</span><span class="nc">ConnectionFactory</span><span class="o">)</span><span class="n">ic</span><span class="o">.</span><span class="na">lookup</span><span class="o">(</span><span class="s">"ConnectionFactory"</span><span class="o">);</span>
<span class="c1">//And look up the Queue:</span>
<span class="nc">Queue</span> <span class="n">orderQueue</span> <span class="o">=</span> <span class="o">(</span><span class="nc">Queue</span><span class="o">)</span><span class="n">ic</span><span class="o">.</span><span class="na">lookup</span><span class="o">(</span><span class="s">"queues/OrderQueue"</span><span class="o">);</span>
<span class="c1">//Next we create a JMS connection using the connection factory:</span>
<span class="nc">Connection</span> <span class="n">connection</span> <span class="o">=</span> <span class="n">cf</span><span class="o">.</span><span class="na">createConnection</span><span class="o">();</span>
<span class="c1">//And we create a non transacted JMS Session, with AUTO\_ACKNOWLe.g. //acknowledge mode:</span>
<span class="nc">Session</span> <span class="n">session</span> <span class="o">=</span> <span class="n">connection</span><span class="o">.</span><span class="na">createSession</span><span class="o">(</span><span class="kc">false</span><span class="o">,</span> <span class="nc">Session</span><span class="o">.</span><span class="na">AUTO_ACKNOWLEDGE</span><span class="o">);</span>
<span class="c1">//We create a MessageProducer that will send orders to the queue:</span>
<span class="nc">MessageProducer</span> <span class="n">producer</span> <span class="o">=</span> <span class="n">session</span><span class="o">.</span><span class="na">createProducer</span><span class="o">(</span><span class="n">orderQueue</span><span class="o">);</span>
<span class="c1">//And we create a MessageConsumer which will consume orders from the</span>
<span class="c1">//queue:</span>
<span class="nc">MessageConsumer</span> <span class="n">consumer</span> <span class="o">=</span> <span class="n">session</span><span class="o">.</span><span class="na">createConsumer</span><span class="o">(</span><span class="n">orderQueue</span><span class="o">);</span>
<span class="c1">//We make sure we start the connection, or delivery won't occur on it:</span>
<span class="n">connection</span><span class="o">.</span><span class="na">start</span><span class="o">();</span>
<span class="c1">//We create a simple TextMessage and send it:</span>
<span class="nc">TextMessage</span> <span class="n">message</span> <span class="o">=</span> <span class="n">session</span><span class="o">.</span><span class="na">createTextMessage</span><span class="o">(</span><span class="s">"This is an order"</span><span class="o">);</span>
<span class="n">producer</span><span class="o">.</span><span class="na">send</span><span class="o">(</span><span class="n">message</span><span class="o">);</span>
<span class="c1">//And we consume the message:</span>
<span class="nc">TextMessage</span> <span class="n">receivedMessage</span> <span class="o">=</span> <span class="o">(</span><span class="nc">TextMessage</span><span class="o">)</span><span class="n">consumer</span><span class="o">.</span><span class="na">receive</span><span class="o">();</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Got order: "</span> <span class="o">+</span> <span class="n">receivedMessage</span><span class="o">.</span><span class="na">getText</span><span class="o">());</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>It is as simple as that.
For a wide range of working JMS examples please see the <a href="examples.html">examples</a>.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="paragraph">
<p><strong>Warning</strong></p>
</div>
<div class="paragraph">
<p>Please note that JMS connections, sessions, producers and consumers are <em>designed to be re-used</em>.</p>
</div>
<div class="paragraph">
<p>It is an anti-pattern to create new connections, sessions, producers and consumers for each message you produce or consume.
If you do this, your application will perform very poorly.
This is discussed further in the section on performance tuning <a href="perf-tuning.html#performance-tuning">Performance Tuning</a>.</p>
</div>
</blockquote>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="directly-instantiating-jms-resources-without-using-jndi"><a class="anchor" href="#directly-instantiating-jms-resources-without-using-jndi"></a><a class="link" href="#directly-instantiating-jms-resources-without-using-jndi">3. Directly instantiating JMS Resources without using JNDI</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>Although it is a very common JMS usage pattern to lookup JMS <em>Administered Objects</em> (that&#8217;s JMS Queue, Topic and ConnectionFactory instances) from JNDI, in some cases you just think "Why do I need JNDI?
Why can&#8217;t I just instantiate these objects directly?"</p>
</div>
<div class="paragraph">
<p>With Apache ActiveMQ Artemis you can do exactly that.
Apache ActiveMQ Artemis supports the direct instantiation of JMS Queue, Topic and ConnectionFactory instances, so you don&#8217;t have to use JNDI at all.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="paragraph">
<p>For a full working example of direct instantiation please look at the <a href="examples.html#instantiate-jms-objects-directly">Instantiate JMS Objects Directly</a> example under the JMS section of the examples.</p>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>Here&#8217;s our simple example, rewritten to not use JNDI at all:</p>
</div>
<div class="paragraph">
<p>We create the JMS ConnectionFactory object via the ActiveMQJMSClient Utility class, note we need to provide connection parameters and specify which transport we are using, for more information on connectors please see <a href="configuring-transports.html#configuring-the-transport">Configuring the Transport</a>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="rouge highlight nowrap"><code data-lang="java"><span class="nc">TransportConfiguration</span> <span class="n">transportConfiguration</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">TransportConfiguration</span><span class="o">(</span><span class="nc">NettyConnectorFactory</span><span class="o">.</span><span class="na">class</span><span class="o">.</span><span class="na">getName</span><span class="o">());</span>
<span class="nc">ConnectionFactory</span> <span class="n">cf</span> <span class="o">=</span> <span class="nc">ActiveMQJMSClient</span><span class="o">.</span><span class="na">createConnectionFactoryWithoutHA</span><span class="o">(</span><span class="nc">JMSFactoryType</span><span class="o">.</span><span class="na">CF</span><span class="o">,</span><span class="n">transportConfiguration</span><span class="o">);</span>
<span class="c1">//We also create the JMS Queue object via the ActiveMQJMSClient Utility</span>
<span class="c1">//class:</span>
<span class="nc">Queue</span> <span class="n">orderQueue</span> <span class="o">=</span> <span class="nc">ActiveMQJMSClient</span><span class="o">.</span><span class="na">createQueue</span><span class="o">(</span><span class="s">"OrderQueue"</span><span class="o">);</span>
<span class="c1">//Next we create a JMS connection using the connection factory:</span>
<span class="nc">Connection</span> <span class="n">connection</span> <span class="o">=</span> <span class="n">cf</span><span class="o">.</span><span class="na">createConnection</span><span class="o">();</span>
<span class="c1">//And we create a non transacted JMS Session, with AUTO\_ACKNOWLe.g. //acknowledge mode:</span>
<span class="nc">Session</span> <span class="n">session</span> <span class="o">=</span> <span class="n">connection</span><span class="o">.</span><span class="na">createSession</span><span class="o">(</span><span class="kc">false</span><span class="o">,</span> <span class="nc">Session</span><span class="o">.</span><span class="na">AUTO_ACKNOWLEDGE</span><span class="o">);</span>
<span class="c1">//We create a MessageProducer that will send orders to the queue:</span>
<span class="nc">MessageProducer</span> <span class="n">producer</span> <span class="o">=</span> <span class="n">session</span><span class="o">.</span><span class="na">createProducer</span><span class="o">(</span><span class="n">orderQueue</span><span class="o">);</span>
<span class="c1">//And we create a MessageConsumer which will consume orders from the</span>
<span class="c1">//queue:</span>
<span class="nc">MessageConsumer</span> <span class="n">consumer</span> <span class="o">=</span> <span class="n">session</span><span class="o">.</span><span class="na">createConsumer</span><span class="o">(</span><span class="n">orderQueue</span><span class="o">);</span>
<span class="c1">//We make sure we start the connection, or delivery won't occur on it:</span>
<span class="n">connection</span><span class="o">.</span><span class="na">start</span><span class="o">();</span>
<span class="c1">//We create a simple TextMessage and send it:</span>
<span class="nc">TextMessage</span> <span class="n">message</span> <span class="o">=</span> <span class="n">session</span><span class="o">.</span><span class="na">createTextMessage</span><span class="o">(</span><span class="s">"This is an order"</span><span class="o">);</span>
<span class="n">producer</span><span class="o">.</span><span class="na">send</span><span class="o">(</span><span class="n">message</span><span class="o">);</span>
<span class="c1">//And we consume the message:</span>
<span class="nc">TextMessage</span> <span class="n">receivedMessage</span> <span class="o">=</span> <span class="o">(</span><span class="nc">TextMessage</span><span class="o">)</span><span class="n">consumer</span><span class="o">.</span><span class="na">receive</span><span class="o">();</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Got order: "</span> <span class="o">+</span> <span class="n">receivedMessage</span><span class="o">.</span><span class="na">getText</span><span class="o">());</span></code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="setting-the-client-id"><a class="anchor" href="#setting-the-client-id"></a><a class="link" href="#setting-the-client-id">4. Setting The Client ID</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>This represents the client id for a JMS client and is needed for creating durable subscriptions.
It is possible to configure this on the connection factory and can be set via the <code>clientId</code> element.
Any connection created by this connection factory will have this set as its client id.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="setting-the-batch-size-for-dups_ok"><a class="anchor" href="#setting-the-batch-size-for-dups_ok"></a><a class="link" href="#setting-the-batch-size-for-dups_ok">5. Setting The Batch Size for DUPS_OK</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>When the JMS acknowledge mode is set to <code>DUPS_OK</code> it is possible to configure the consumer so that it sends acknowledgements in batches rather that one at a time, saving valuable bandwidth.
This can be configured via the connection factory via the <code>dupsOkBatchSize</code> element and is set in bytes.
The default is 1024 * 1024 bytes = 1 MiB.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="setting-the-transaction-batch-size"><a class="anchor" href="#setting-the-transaction-batch-size"></a><a class="link" href="#setting-the-transaction-batch-size">6. Setting The Transaction Batch Size</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>When receiving messages in a transaction it is possible to configure the consumer to send acknowledgements in batches rather than individually saving valuable bandwidth.
This can be configured on the connection factory via the <code>transactionBatchSize</code> element and is set in bytes.
The default is 1024 * 1024.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="setting-the-destination-cache"><a class="anchor" href="#setting-the-destination-cache"></a><a class="link" href="#setting-the-destination-cache">7. Setting The Destination Cache</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>Many frameworks such as Spring resolve the destination by name on every operation, this can cause a performance issue and extra calls to the broker, in a scenario where destinations (addresses) are permanent broker side, such as they are managed by a platform or operations team.
using <code>cacheDestinations</code> element, you can toggle on the destination cache to improve the performance and reduce the calls to the broker.
This should not be used if destinations (addresses) are not permanent broker side, as in dynamic creation/deletion.</p>
</div>
</div>
</div>
</div>
</body>
</html>