blob: cad376832204e182612e3227d86182bfc10eac52 [file] [log] [blame]
<!DOCTYPE HTML>
<html lang="" >
<head>
<meta charset="UTF-8">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>Using JMS ยท ActiveMQ Artemis Documentation</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="description" content="">
<meta name="generator" content="GitBook 3.2.3">
<link rel="stylesheet" href="gitbook/style.css">
<link rel="stylesheet" href="gitbook/gitbook-plugin-highlight/website.css">
<link rel="stylesheet" href="gitbook/gitbook-plugin-search/search.css">
<link rel="stylesheet" href="gitbook/gitbook-plugin-fontsettings/website.css">
<meta name="HandheldFriendly" content="true"/>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<link rel="apple-touch-icon-precomposed" sizes="152x152" href="gitbook/images/apple-touch-icon-precomposed-152.png">
<link rel="shortcut icon" href="gitbook/images/favicon.ico" type="image/x-icon">
<link rel="next" href="client-classpath.html" />
<link rel="prev" href="jms-core-mapping.html" />
</head>
<body>
<div class="book">
<div class="book-summary">
<div id="book-search-input" role="search">
<input type="text" placeholder="Type to search" />
</div>
<nav role="navigation">
<ul class="summary">
<li class="chapter " data-level="1.1" data-path="./">
<a href="./">
Introduction
</a>
</li>
<li class="chapter " data-level="1.2" data-path="notice.html">
<a href="notice.html">
Legal Notice
</a>
</li>
<li class="chapter " data-level="1.3" data-path="preface.html">
<a href="preface.html">
Preface
</a>
</li>
<li class="chapter " data-level="1.4" data-path="project-info.html">
<a href="project-info.html">
Project Info
</a>
</li>
<li class="chapter " data-level="1.5" data-path="versions.html">
<a href="versions.html">
Versions
</a>
</li>
<li class="chapter " data-level="1.6" data-path="messaging-concepts.html">
<a href="messaging-concepts.html">
Messaging Concepts
</a>
</li>
<li class="chapter " data-level="1.7" data-path="architecture.html">
<a href="architecture.html">
Architecture
</a>
</li>
<li class="chapter " data-level="1.8" data-path="using-server.html">
<a href="using-server.html">
Using the Server
</a>
</li>
<li class="chapter " data-level="1.9" data-path="upgrading.html">
<a href="upgrading.html">
Upgrading
</a>
</li>
<li class="chapter " data-level="1.10" data-path="address-model.html">
<a href="address-model.html">
Address Model
</a>
</li>
<li class="chapter " data-level="1.11" data-path="protocols-interoperability.html">
<a href="protocols-interoperability.html">
Protocols and Interoperability
</a>
</li>
<li class="chapter " data-level="1.12" data-path="amqp.html">
<a href="amqp.html">
AMQP
</a>
</li>
<li class="chapter " data-level="1.13" data-path="mqtt.html">
<a href="mqtt.html">
MQTT
</a>
</li>
<li class="chapter " data-level="1.14" data-path="stomp.html">
<a href="stomp.html">
STOMP
</a>
</li>
<li class="chapter " data-level="1.15" data-path="openwire.html">
<a href="openwire.html">
OpenWire
</a>
</li>
<li class="chapter " data-level="1.16" data-path="core.html">
<a href="core.html">
Core
</a>
</li>
<li class="chapter " data-level="1.17" data-path="jms-core-mapping.html">
<a href="jms-core-mapping.html">
Mapping JMS Concepts to the Core API
</a>
</li>
<li class="chapter active" data-level="1.18" data-path="using-jms.html">
<a href="using-jms.html">
Using JMS
</a>
</li>
<li class="chapter " data-level="1.19" data-path="client-classpath.html">
<a href="client-classpath.html">
The Client Classpath
</a>
</li>
<li class="chapter " data-level="1.20" data-path="examples.html">
<a href="examples.html">
Examples
</a>
</li>
<li class="chapter " data-level="1.21" data-path="wildcard-routing.html">
<a href="wildcard-routing.html">
Routing Messages With Wild Cards
</a>
</li>
<li class="chapter " data-level="1.22" data-path="wildcard-syntax.html">
<a href="wildcard-syntax.html">
Wildcard Syntax
</a>
</li>
<li class="chapter " data-level="1.23" data-path="filter-expressions.html">
<a href="filter-expressions.html">
Filter Expressions
</a>
</li>
<li class="chapter " data-level="1.24" data-path="persistence.html">
<a href="persistence.html">
Persistence
</a>
</li>
<li class="chapter " data-level="1.25" data-path="configuring-transports.html">
<a href="configuring-transports.html">
Configuring Transports
</a>
</li>
<li class="chapter " data-level="1.26" data-path="config-reload.html">
<a href="config-reload.html">
Configuration Reload
</a>
</li>
<li class="chapter " data-level="1.27" data-path="connection-ttl.html">
<a href="connection-ttl.html">
Detecting Dead Connections
</a>
</li>
<li class="chapter " data-level="1.28" data-path="slow-consumers.html">
<a href="slow-consumers.html">
Detecting Slow Consumers
</a>
</li>
<li class="chapter " data-level="1.29" data-path="network-isolation.html">
<a href="network-isolation.html">
Avoiding Network Isolation
</a>
</li>
<li class="chapter " data-level="1.30" data-path="critical-analysis.html">
<a href="critical-analysis.html">
Detecting Broker Issues (Critical Analysis)
</a>
</li>
<li class="chapter " data-level="1.31" data-path="transaction-config.html">
<a href="transaction-config.html">
Resource Manager Configuration
</a>
</li>
<li class="chapter " data-level="1.32" data-path="flow-control.html">
<a href="flow-control.html">
Flow Control
</a>
</li>
<li class="chapter " data-level="1.33" data-path="send-guarantees.html">
<a href="send-guarantees.html">
Guarantees of sends and commits
</a>
</li>
<li class="chapter " data-level="1.34" data-path="undelivered-messages.html">
<a href="undelivered-messages.html">
Message Redelivery and Undelivered Messages
</a>
</li>
<li class="chapter " data-level="1.35" data-path="message-expiry.html">
<a href="message-expiry.html">
Message Expiry
</a>
</li>
<li class="chapter " data-level="1.36" data-path="large-messages.html">
<a href="large-messages.html">
Large Messages
</a>
</li>
<li class="chapter " data-level="1.37" data-path="paging.html">
<a href="paging.html">
Paging
</a>
</li>
<li class="chapter " data-level="1.38" data-path="scheduled-messages.html">
<a href="scheduled-messages.html">
Scheduled Messages
</a>
</li>
<li class="chapter " data-level="1.39" data-path="last-value-queues.html">
<a href="last-value-queues.html">
Last-Value Queues
</a>
</li>
<li class="chapter " data-level="1.40" data-path="ring-queues.html">
<a href="ring-queues.html">
Ring Queues
</a>
</li>
<li class="chapter " data-level="1.41" data-path="retroactive-addresses.html">
<a href="retroactive-addresses.html">
Retroactive Addresses
</a>
</li>
<li class="chapter " data-level="1.42" data-path="exclusive-queues.html">
<a href="exclusive-queues.html">
Exclusive Queues
</a>
</li>
<li class="chapter " data-level="1.43" data-path="message-grouping.html">
<a href="message-grouping.html">
Message Grouping
</a>
</li>
<li class="chapter " data-level="1.44" data-path="consumer-priority.html">
<a href="consumer-priority.html">
Consumer Priority
</a>
</li>
<li class="chapter " data-level="1.45" data-path="pre-acknowledge.html">
<a href="pre-acknowledge.html">
Extra Acknowledge Modes
</a>
</li>
<li class="chapter " data-level="1.46" data-path="management.html">
<a href="management.html">
Management
</a>
</li>
<li class="chapter " data-level="1.47" data-path="management-console.html">
<a href="management-console.html">
Management Console
</a>
</li>
<li class="chapter " data-level="1.48" data-path="metrics.html">
<a href="metrics.html">
Metrics
</a>
</li>
<li class="chapter " data-level="1.49" data-path="security.html">
<a href="security.html">
Security
</a>
</li>
<li class="chapter " data-level="1.50" data-path="masking-passwords.html">
<a href="masking-passwords.html">
Masking Passwords
</a>
</li>
<li class="chapter " data-level="1.51" data-path="broker-plugins.html">
<a href="broker-plugins.html">
Broker Plugins
</a>
</li>
<li class="chapter " data-level="1.52" data-path="resource-limits.html">
<a href="resource-limits.html">
Resource Limits
</a>
</li>
<li class="chapter " data-level="1.53" data-path="jms-bridge.html">
<a href="jms-bridge.html">
The JMS Bridge
</a>
</li>
<li class="chapter " data-level="1.54" data-path="client-reconnection.html">
<a href="client-reconnection.html">
Client Reconnection and Session Reattachment
</a>
</li>
<li class="chapter " data-level="1.55" data-path="diverts.html">
<a href="diverts.html">
Diverting and Splitting Message Flows
</a>
</li>
<li class="chapter " data-level="1.56" data-path="core-bridges.html">
<a href="core-bridges.html">
Core Bridges
</a>
</li>
<li class="chapter " data-level="1.57" data-path="transformers.html">
<a href="transformers.html">
Transformers
</a>
</li>
<li class="chapter " data-level="1.58" data-path="duplicate-detection.html">
<a href="duplicate-detection.html">
Duplicate Message Detection
</a>
</li>
<li class="chapter " data-level="1.59" data-path="clusters.html">
<a href="clusters.html">
Clusters
</a>
</li>
<li class="chapter " data-level="1.60" data-path="federation.html">
<a href="federation.html">
Federation
</a>
<ul class="articles">
<li class="chapter " data-level="1.60.1" data-path="federation-address.html">
<a href="federation-address.html">
Address Federation
</a>
</li>
<li class="chapter " data-level="1.60.2" data-path="federation-queue.html">
<a href="federation-queue.html">
Queue Federation
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="1.61" data-path="ha.html">
<a href="ha.html">
High Availability and Failover
</a>
</li>
<li class="chapter " data-level="1.62" data-path="graceful-shutdown.html">
<a href="graceful-shutdown.html">
Graceful Server Shutdown
</a>
</li>
<li class="chapter " data-level="1.63" data-path="libaio.html">
<a href="libaio.html">
Libaio Native Libraries
</a>
</li>
<li class="chapter " data-level="1.64" data-path="thread-pooling.html">
<a href="thread-pooling.html">
Thread management
</a>
</li>
<li class="chapter " data-level="1.65" data-path="web-server.html">
<a href="web-server.html">
Embedded Web Server
</a>
</li>
<li class="chapter " data-level="1.66" data-path="logging.html">
<a href="logging.html">
Logging
</a>
</li>
<li class="chapter " data-level="1.67" data-path="rest.html">
<a href="rest.html">
REST Interface
</a>
</li>
<li class="chapter " data-level="1.68" data-path="embedding-activemq.html">
<a href="embedding-activemq.html">
Embedding the Broker
</a>
</li>
<li class="chapter " data-level="1.69" data-path="karaf.html">
<a href="karaf.html">
Apache Karaf
</a>
</li>
<li class="chapter " data-level="1.70" data-path="tomcat.html">
<a href="tomcat.html">
Apache Tomcat
</a>
</li>
<li class="chapter " data-level="1.71" data-path="spring-integration.html">
<a href="spring-integration.html">
Spring Integration
</a>
</li>
<li class="chapter " data-level="1.72" data-path="cdi-integration.html">
<a href="cdi-integration.html">
CDI Integration
</a>
</li>
<li class="chapter " data-level="1.73" data-path="intercepting-operations.html">
<a href="intercepting-operations.html">
Intercepting Operations
</a>
</li>
<li class="chapter " data-level="1.74" data-path="data-tools.html">
<a href="data-tools.html">
Data Tools
</a>
</li>
<li class="chapter " data-level="1.75" data-path="maven-plugin.html">
<a href="maven-plugin.html">
Maven Plugin
</a>
</li>
<li class="chapter " data-level="1.76" data-path="unit-testing.html">
<a href="unit-testing.html">
Unit Testing
</a>
</li>
<li class="chapter " data-level="1.77" data-path="perf-tuning.html">
<a href="perf-tuning.html">
Troubleshooting and Performance Tuning
</a>
</li>
<li class="chapter " data-level="1.78" data-path="configuration-index.html">
<a href="configuration-index.html">
Configuration Reference
</a>
</li>
<li class="divider"></li>
<li>
<a href="https://www.gitbook.com" target="blank" class="gitbook-link">
Published with GitBook
</a>
</li>
</ul>
</nav>
</div>
<div class="book-body">
<div class="body-inner">
<div class="book-header" role="navigation">
<!-- Title -->
<h1>
<i class="fa fa-circle-o-notch fa-spin"></i>
<a href="." >Using JMS</a>
</h1>
</div>
<div class="page-wrapper" tabindex="-1" role="main">
<div class="page-inner">
<div id="book-search-results">
<div class="search-noresults">
<section class="normal markdown-section">
<h1 id="using-jms">Using JMS</h1>
<p>Although Apache ActiveMQ Artemis provides a JMS agnostic messaging API, many
users will be more comfortable using JMS.</p>
<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" target="_blank">Oracle JMS
tutorial</a> - a full
JMS tutorial is out of scope for this guide.</p>
<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</a>.</p>
<p>In this section we&apos;ll go through the main steps in configuring the server for
JMS and creating a simple JMS program. We&apos;ll also show how to configure and use
JNDI, and also how to use JMS with Apache ActiveMQ Artemis without using any
JNDI.</p>
<h2 id="a-simple-ordering-system">A simple ordering system</h2>
<p>For this chapter we&apos;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>
<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>
<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>
<h2 id="jndi">JNDI</h2>
<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&apos;s look at the different kinds of administered
objects and how to configure them.</p>
<blockquote>
<p><strong>Note:</strong></p>
<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>
</blockquote>
<h3 id="connectionfactory-jndi">ConnectionFactory JNDI</h3>
<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>
<p>Here&apos;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>
<pre><code class="lang-properties">java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
connectionFactory.invmConnectionFactory=vm://0
</code></pre>
<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>
<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>
<pre><code class="lang-properties">java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
connectionFactory.invmConnectionFactory0=vm://0
connectionFactory.invmConnectionFactory1=vm://1
connectionFactory.invmConnectionFactory2=vm://2
</code></pre>
<p>Here is a list of all the supported URL schemes:</p>
<ul>
<li><code>vm</code></li>
<li><code>tcp</code></li>
<li><code>udp</code></li>
<li><code>jgroups</code></li>
</ul>
<p>Most clients won&apos;t be connecting to an embedded broker. Clients will most
commonly connect across a network a remote broker. Here&apos;s a simple example of a
client configuring a connection factory to connect to a remote broker running
on myhost:5445:</p>
<pre><code class="lang-properties">java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
connectionFactory.ConnectionFactory=tcp://myhost:5445
</code></pre>
<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>
<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>
<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>
<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>
<p>Note if you are using the <code>tcp</code> scheme and multiple addresses then a query can
be applied to all the url&apos;s or just to an individual connector, so where you
have</p>
<ul>
<li><code>(tcp://remote-host1:5445?httpEnabled=true,remote-host2:5445?httpEnabled=true)?clientID=1234</code></li>
</ul>
<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>
<p>The <code>udp</code> scheme supports 4 properties:</p>
<ul>
<li><p><code>localAddress</code> - If you are running with multiple network
interfaces on the same machine, you may want to specify that the
discovery group listens only only a specific interface. To do this
you can specify the interface address with this parameter.</p>
</li>
<li><p><code>localPort</code> - 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>
</li>
<li><p><code>refreshTimeout</code> - 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>
</li>
<li><p><code>discoveryInitialWaitTimeout</code> - 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>
</li>
</ul>
<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 either
<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 or it can be
<code>jgroups://channelName?properties=some-jgroups-properties</code>. In both instance
the <code>channelName</code> is the name given to the jgroups channel created.</p>
<p>The <code>refreshTimeout</code> and <code>discoveryInitialWaitTimeout</code> properties are supported
just like with <code>udp</code>.</p>
<p>The default type for the default connection factory is of type
<code>javax.jms.ConnectionFactory</code>. This can be changed by setting the type like so</p>
<pre><code class="lang-properties">java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
java.naming.provider.url=tcp://localhost:5445?type=CF
</code></pre>
<p>In this example it is still set to the default, below shows a list of types
that can be set.</p>
<h4 id="configuration-for-connection-factory-types">Configuration for Connection Factory Types</h4>
<table>
<thead>
<tr>
<th>type</th>
<th>interface</th>
</tr>
</thead>
<tbody>
<tr>
<td>CF (default)</td>
<td>javax.jms.ConnectionFactory</td>
</tr>
<tr>
<td>XA_CF</td>
<td>javax.jms.XAConnectionFactory</td>
</tr>
<tr>
<td>QUEUE_CF</td>
<td>javax.jms.QueueConnectionFactory</td>
</tr>
<tr>
<td>QUEUE_XA_CF</td>
<td>javax.jms.XAQueueConnectionFactory</td>
</tr>
<tr>
<td>TOPIC_CF</td>
<td>javax.jms.TopicConnectionFactory</td>
</tr>
<tr>
<td>TOPIC_XA_CF</td>
<td>javax.jms.XATopicConnectionFactory</td>
</tr>
</tbody>
</table>
<h3 id="destination-jndi">Destination JNDI</h3>
<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>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">address</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;OrderQueue&quot;</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">queue</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;OrderQueue&quot;</span>/&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">address</span>&gt;</span>
</code></pre>
<p>And if the client wanted to bind this queue to &quot;queues/OrderQueue&quot; then the
JNDI properties would be configured like so:</p>
<pre><code class="lang-properties">java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
java.naming.provider.url=tcp://myhost:5445
queue.queues/OrderQueue=OrderQueue
</code></pre>
<p>It is also possible to look-up JMS destinations which haven&apos;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 &quot;OrderQueue&quot; it could do so simply
by using the string &quot;dynamicQueues/OrderQueue&quot;. 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>
<h3 id="the-code">The code</h3>
<p>Here&apos;s the code for the example:</p>
<p>First we&apos;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>
<pre><code class="lang-java">InitialContext ic = <span class="hljs-keyword">new</span> InitialContext();
<span class="hljs-comment">//Now we&apos;ll look up the connection factory from which we can create</span>
<span class="hljs-comment">//connections to myhost:5445:</span>
ConnectionFactory cf = (ConnectionFactory)ic.lookup(<span class="hljs-string">&quot;ConnectionFactory&quot;</span>);
<span class="hljs-comment">//And look up the Queue:</span>
Queue orderQueue = (Queue)ic.lookup(<span class="hljs-string">&quot;queues/OrderQueue&quot;</span>);
<span class="hljs-comment">//Next we create a JMS connection using the connection factory:</span>
Connection connection = cf.createConnection();
<span class="hljs-comment">//And we create a non transacted JMS Session, with AUTO\_ACKNOWLEDGE</span>
<span class="hljs-comment">//acknowledge mode:</span>
Session session = connection.createSession(<span class="hljs-keyword">false</span>, Session.AUTO_ACKNOWLEDGE);
<span class="hljs-comment">//We create a MessageProducer that will send orders to the queue:</span>
MessageProducer producer = session.createProducer(orderQueue);
<span class="hljs-comment">//And we create a MessageConsumer which will consume orders from the</span>
<span class="hljs-comment">//queue:</span>
MessageConsumer consumer = session.createConsumer(orderQueue);
<span class="hljs-comment">//We make sure we start the connection, or delivery won&apos;t occur on it:</span>
connection.start();
<span class="hljs-comment">//We create a simple TextMessage and send it:</span>
TextMessage message = session.createTextMessage(<span class="hljs-string">&quot;This is an order&quot;</span>);
producer.send(message);
<span class="hljs-comment">//And we consume the message:</span>
TextMessage receivedMessage = (TextMessage)consumer.receive();
System.out.println(<span class="hljs-string">&quot;Got order: &quot;</span> + receivedMessage.getText());
</code></pre>
<p>It is as simple as that. For a wide range of working JMS examples please
see the examples directory in the distribution.</p>
<blockquote>
<p><strong>Warning</strong></p>
<p>Please note that JMS connections, sessions, producers and consumers are
<em>designed to be re-used</em>.</p>
<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</a>.</p>
</blockquote>
<h2 id="directly-instantiating-jms-resources-without-using-jndi">Directly instantiating JMS Resources without using JNDI</h2>
<p>Although it is a very common JMS usage pattern to lookup JMS <em>Administered
Objects</em> (that&apos;s JMS Queue, Topic and ConnectionFactory instances) from JNDI,
in some cases you just think &quot;Why do I need JNDI? Why can&apos;t I just instantiate
these objects directly?&quot;</p>
<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&apos;t have to use JNDI at all.</p>
<blockquote>
<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>
</blockquote>
<p>Here&apos;s our simple example, rewritten to not use JNDI at all:</p>
<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</a>.</p>
<pre><code class="lang-java">TransportConfiguration transportConfiguration = <span class="hljs-keyword">new</span> TransportConfiguration(NettyConnectorFactory.class.getName());
ConnectionFactory cf = ActiveMQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF,transportConfiguration);
<span class="hljs-comment">//We also create the JMS Queue object via the ActiveMQJMSClient Utility</span>
<span class="hljs-comment">//class:</span>
Queue orderQueue = ActiveMQJMSClient.createQueue(<span class="hljs-string">&quot;OrderQueue&quot;</span>);
<span class="hljs-comment">//Next we create a JMS connection using the connection factory:</span>
Connection connection = cf.createConnection();
<span class="hljs-comment">//And we create a non transacted JMS Session, with AUTO\_ACKNOWLEDGE</span>
<span class="hljs-comment">//acknowledge mode:</span>
Session session = connection.createSession(<span class="hljs-keyword">false</span>, Session.AUTO_ACKNOWLEDGE);
<span class="hljs-comment">//We create a MessageProducer that will send orders to the queue:</span>
MessageProducer producer = session.createProducer(orderQueue);
<span class="hljs-comment">//And we create a MessageConsumer which will consume orders from the</span>
<span class="hljs-comment">//queue:</span>
MessageConsumer consumer = session.createConsumer(orderQueue);
<span class="hljs-comment">//We make sure we start the connection, or delivery won&apos;t occur on it:</span>
connection.start();
<span class="hljs-comment">//We create a simple TextMessage and send it:</span>
TextMessage message = session.createTextMessage(<span class="hljs-string">&quot;This is an order&quot;</span>);
producer.send(message);
<span class="hljs-comment">//And we consume the message:</span>
TextMessage receivedMessage = (TextMessage)consumer.receive();
System.out.println(<span class="hljs-string">&quot;Got order: &quot;</span> + receivedMessage.getText());
</code></pre>
<h2 id="setting-the-client-id">Setting The Client ID</h2>
<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>
<h2 id="setting-the-batch-size-for-dupsok">Setting The Batch Size for DUPS_OK</h2>
<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>
<h2 id="setting-the-transaction-batch-size">Setting The Transaction Batch Size</h2>
<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>
<h2 id="setting-the-destination-cache">Setting The Destination Cache</h2>
<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>
</section>
</div>
<div class="search-results">
<div class="has-results">
<h1 class="search-results-title"><span class='search-results-count'></span> results matching "<span class='search-query'></span>"</h1>
<ul class="search-results-list"></ul>
</div>
<div class="no-results">
<h1 class="search-results-title">No results matching "<span class='search-query'></span>"</h1>
</div>
</div>
</div>
</div>
</div>
</div>
<a href="jms-core-mapping.html" class="navigation navigation-prev " aria-label="Previous page: Mapping JMS Concepts to the Core API">
<i class="fa fa-angle-left"></i>
</a>
<a href="client-classpath.html" class="navigation navigation-next " aria-label="Next page: The Client Classpath">
<i class="fa fa-angle-right"></i>
</a>
</div>
<script>
var gitbook = gitbook || [];
gitbook.push(function() {
gitbook.page.hasChanged({"page":{"title":"Using JMS","level":"1.18","depth":1,"next":{"title":"The Client Classpath","level":"1.19","depth":1,"path":"client-classpath.md","ref":"client-classpath.md","articles":[]},"previous":{"title":"Mapping JMS Concepts to the Core API","level":"1.17","depth":1,"path":"jms-core-mapping.md","ref":"jms-core-mapping.md","articles":[]},"dir":"ltr"},"config":{"plugins":[],"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"pluginsConfig":{"highlight":{},"search":{},"lunr":{"maxIndexSize":1000000,"ignoreSpecialCharacters":false},"sharing":{"facebook":true,"twitter":true,"google":false,"weibo":false,"instapaper":false,"vk":false,"all":["facebook","google","twitter","weibo","instapaper"]},"fontsettings":{"theme":"white","family":"sans","size":2},"theme-default":{"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"showLevel":false}},"github":"apache/activemq-artemis","theme":"default","githubHost":"https://github.com/","pdf":{"pageNumbers":true,"fontSize":12,"fontFamily":"Arial","paperSize":"a4","chapterMark":"pagebreak","pageBreaksBefore":"/","margin":{"right":62,"left":62,"top":56,"bottom":56}},"structure":{"langs":"LANGS.md","readme":"README.md","glossary":"GLOSSARY.md","summary":"SUMMARY.md"},"variables":{},"title":"ActiveMQ Artemis Documentation","links":{"home":"http://activemq.apache.org/artemis","issues":"https://issues.apache.org/jira/browse/ARTEMIS","contribute":"http://activemq.apache.org/contributing.html"},"gitbook":"3.x.x","description":"ActiveMQ Artemis User Guide and Reference Documentation"},"file":{"path":"using-jms.md","mtime":"2020-01-10T14:13:27.000Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2020-01-10T14:51:01.535Z"},"basePath":".","book":{"language":""}});
});
</script>
</div>
<script src="gitbook/gitbook.js"></script>
<script src="gitbook/theme.js"></script>
<script src="gitbook/gitbook-plugin-search/search-engine.js"></script>
<script src="gitbook/gitbook-plugin-search/search.js"></script>
<script src="gitbook/gitbook-plugin-lunr/lunr.min.js"></script>
<script src="gitbook/gitbook-plugin-lunr/search-lunr.js"></script>
<script src="gitbook/gitbook-plugin-sharing/buttons.js"></script>
<script src="gitbook/gitbook-plugin-fontsettings/fontsettings.js"></script>
</body>
</html>