Author: timfox
Date: 2010-01-07 08:52:32 -0500 (Thu, 07 Jan 2010)
New Revision: 8768
Modified:
trunk/docs/user-manual/en/client-classpath.xml
trunk/docs/user-manual/en/using-core.xml
trunk/docs/user-manual/en/using-jms.xml
Log:
user manual edits part 2
Modified: trunk/docs/user-manual/en/client-classpath.xml
===================================================================
--- trunk/docs/user-manual/en/client-classpath.xml 2010-01-07 13:25:20 UTC (rev 8767)
+++ trunk/docs/user-manual/en/client-classpath.xml 2010-01-07 13:52:32 UTC (rev 8768)
@@ -19,35 +19,34 @@
<chapter id="client-classpath">
<title>The Client Classpath</title>
<para>HornetQ requires several jars on the <emphasis>Client
Classpath</emphasis> depending on
- whether the client uses HornetQ Core API, JMS, and JNDI.</para>
- <note>
+ whether the client uses HornetQ Core API, JMS, and JNDI.</para>
+ <warning>
<para>All the jars mentioned here can be found in the
<literal>lib</literal> directory of
the HornetQ distribution. Be sure you only use the jars from the correct
version of the
release, you <emphasis>must not</emphasis> mix and match versions
of jars from different
HornetQ versions. Mixing and matching different jar versions may cause subtle
errors and
failures to occur.</para>
- </note>
+ </warning>
<section>
<title>HornetQ Core Client</title>
<para>If you are using just a pure HornetQ Core client (i.e. no JMS) then
you need <literal
- >hornetq-core-client.jar</literal>,
<literal>hornetq-transports.jar</literal>
- and <literal>netty.jar</literal> on your client
classpath.</para>
+ >hornetq-core-client.jar</literal>,
<literal>hornetq-transports.jar</literal> and
+ <literal>netty.jar</literal> on your client
classpath.</para>
</section>
<section>
<title>JMS Client</title>
- <para>If you are using JMS on the client side, then you will also need to
include
- <literal>hornetq-jms-client.jar</literal> and
<literal>jboss-jms-api.jar</literal>.</para>
+ <para>If you are using JMS on the client side, then you will also need to
include <literal
+ >hornetq-jms-client.jar</literal> and
<literal>jboss-jms-api.jar</literal>.</para>
<note>
- <para><literal>jboss-jms-api.jar</literal>
- just contains Java EE API interface classes needed for the <literal
- >javax.jms.*</literal> classes. If you already have a jar with
these interface
- classes on your classpath, you will not need it.</para>
- </note>
+ <para><literal>jboss-jms-api.jar</literal> just contains
Java EE API interface classes
+ needed for the <literal>javax.jms.*</literal> classes. If you
already have a jar
+ with these interface classes on your classpath, you will not need
it.</para>
+ </note>
</section>
<section>
<title>JMS Client with JNDI</title>
<para>If you are looking up JMS resources from the JNDI server co-located
with the HornetQ
- standalone server, you wil also need the jar
<literal>jnp-client.jar</literal> jar on your
- client classpath as well as any other jars mentioned
previously.</para>
+ standalone server, you wil also need the jar
<literal>jnp-client.jar</literal> jar on
+ your client classpath as well as any other jars mentioned
previously.</para>
</section>
</chapter>
Modified: trunk/docs/user-manual/en/using-core.xml
===================================================================
--- trunk/docs/user-manual/en/using-core.xml 2010-01-07 13:25:20 UTC (rev 8767)
+++ trunk/docs/user-manual/en/using-core.xml 2010-01-07 13:52:32 UTC (rev 8768)
@@ -18,7 +18,8 @@
<!-- =============================================================================
-->
<chapter id="using-core">
<title>Using Core</title>
- <para>HornetQ core is a completely JMS-agnostic messaging system with its own
core API.</para>
+ <para>HornetQ core is a completely JMS-agnostic messaging system with its own
non-JMS API. We
+ call this the <emphasis>core API</emphasis>.</para>
<para>If you don't want to use JMS you can use the core API directly. The
core API provides all
the functionality of JMS but without much of the complexity. It also provides
features that
are not available using JMS.</para>
@@ -26,40 +27,67 @@
<title>Core Messaging Concepts</title>
<para>Some of the core messaging concepts are similar to JMS concepts, but
core messaging
concepts differ in some ways. In general the core messaging API is simpler
than the JMS
- API, since we remove distinctions between queues, topics and subscriptions.
We'll
+ API, since we remove distinctions between queues, topics and subscriptions.
We'll
discuss each of the major core messaging concepts in turn, but to see the API
in detail,
please consult the Javadoc.</para>
<section>
<title>Message</title>
- <para>A message is the unit of data which is sent between clients and
servers.</para>
- <para>A message has a body which is effectively a byte[], it also has a
set of
- properties which are key-value pairs. Each property key is a string and
property
- values can be of type integer, long, short, byte, byte[], String, double,
float or
- boolean.</para>
- <para>A message has an <emphasis>address</emphasis> it is
being sent to.
- When the message arrives on the server it is routed to any queues
- that are bound to the address. An address may have many queues bound to
it or even
- none. There may also be entities other than queues, like <emphasis
role="italic"
- >diverts</emphasis> bound to addresses.</para>
- <para>Messages can be either durable or non durable. Durable messages
in a durable queue
- will survive a server crash or restart. Non durable messages will never
survive a
- server crash or restart.</para>
- <para>Messages can be specified with a priority value between 0 and 9.
0 represents the
- lowest priority and 9 represents the highest. HornetQ will attempt to
deliver higher
- priority messages before lower priority ones.</para>
- <para>Messages can be specified with an optional expiry time. HornetQ
will not deliver
- messages after its expiry time has been exceeded.</para>
- <para>Messages also have an optional timestamp which represents the
time the message was
- sent.</para>
+ <itemizedlist>
+ <listitem>
+ <para>A message is the unit of data which is sent between
clients and
+ servers.</para>
+ </listitem>
+ <listitem>
+ <para>A message has a body which is a buffer containing
convenient methods for
+ reading and writing data into it.</para>
+ </listitem>
+ <listitem>
+ <para>A message has a set of properties which are key-value
pairs. Each property
+ key is a string and property values can be of type integer, long,
short,
+ byte, byte[], String, double, float or boolean.</para>
+ </listitem>
+ <listitem>
+ <para>A message has an <emphasis>address</emphasis>
it is being sent to. When
+ the message arrives on the server it is routed to any queues that
are bound
+ to the address - if the queues are bound with any filter, the
message will
+ only be routed to that queue if the filter matches. An address
may have many
+ queues bound to it or even none. There may also be entities other
than
+ queues, like <emphasis
role="italic">diverts</emphasis> bound to
+ addresses.</para>
+ </listitem>
+ <listitem>
+ <para>Messages can be either durable or non durable. Durable
messages in a
+ durable queue will survive a server crash or restart. Non durable
messages
+ will never survive a server crash or restart.</para>
+ </listitem>
+ <listitem>
+ <para>Messages can be specified with a priority value between 0
and 9. 0
+ represents the lowest priority and 9 represents the highest.
HornetQ will
+ attempt to deliver higher priority messages before lower
priority
+ ones.</para>
+ </listitem>
+ <listitem>
+ <para>Messages can be specified with an optional expiry time.
HornetQ will not
+ deliver messages after its expiry time has been
exceeded.</para>
+ </listitem>
+ <listitem>
+ <para>Messages also have an optional timestamp which represents
the time the
+ message was sent.</para>
+ </listitem>
+ <listitem>
+ <para>HornetQ also supports the sending/consuming of very large
messages - much
+ larger than can fit in available RAM at any one
time.</para>
+ </listitem>
+ </itemizedlist>
</section>
<section>
<title>Address</title>
<para>A server maintains a mapping between an address and a set of
queues. Zero or more
queues can be bound to a single address. Each queue can be bound with an
optional
- message filter. When a message is routed, it is in fact routed to the set
of
- queues bound to the message's address. If any of the queues are
bound
- with a filter expression, then the message will only be routed to the
subset of
- bound queues which match that filter expression.</para>
+ message filter. When a message is routed, it is routed to the set of
queues bound to
+ the message's address. If any of the queues are bound with a filter
expression, then
+ the message will only be routed to the subset of bound queues which match
that
+ filter expression.</para>
<para>Other entities, such as <emphasis
role="italic">diverts</emphasis> can also be
bound to an address and messages will also be routed there.</para>
<note>
@@ -92,6 +120,8 @@
ClientSession</literal> instances.
<literal>ClientSessionFactory</literal>
instances know
how to connect to the server to create sessions, and are configurable
with many settings.</para>
+ <para><literal>ClientSessionFactory</literal> instances are
created using the <literal
+ >HornetQClient</literal> factory class.</para>
</section>
<section>
<title>ClientSession</title>
@@ -102,6 +132,16 @@
of a <ulink
url="http://java.sun.com/javaee/technologies/jta/index.jsp">...
transaction.</para>
<para>ClientSession instances group ClientConsumers and
ClientProducers.</para>
+ <para>ClientSession instances can be registered with an optional
<literal
+ >SendAcknowledgementHandler</literal>. This allows your
client code to be
+ notified asynchronously when sent messages have successfully reached the
server.
+ This unique HornetQ feature, allows you to have full guarantees that sent
messages
+ have reached the server without having to block on each message sent
until a
+ response is received. Blocking on each messages sent is costly since it
requires a
+ network round trip for each message sent. By not blocking and receiving
send
+ acknowledgements asynchronously you can create true end to end
asynchronous systems
+ which is not possible using the standard JMS API. For more information on
this
+ advanced feature please see the section <xref
linkend="send-guarantees"/>.</para>
</section>
<section>
<title>ClientConsumer</title>
@@ -119,6 +159,14 @@
have no specified address, and the address is specified at send time for
the
message.</para>
</section>
+ <warning>
+ <para>Please note that ClientSession, ClientProducer and ClientConsumer
instances are
+ <emphasis>designed to be re-used</emphasis>.</para>
+ <para>It's an anti-pattern to create new ClientSession,
ClientProducer and ClientConsumer instances
+ 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
+ <xref linkend="perf-tuning"/>.</para>
+ </warning>
</section>
<section>
<title>A simple example of using Core</title>
@@ -137,7 +185,7 @@
ClientMessage message = session.createMessage(true);
-message.getBody().writeString("Hello");
+message.getBodyBuffer().writeString("Hello");
producer.send(message);
@@ -147,7 +195,7 @@
ClientMessage msgReceived = consumer.receive();
-System.out.println("message = " + msgReceived.getBody().readString());
+System.out.println("message = " + msgReceived.getBodyBuffer().readString());
session.close();</programlisting>
</section>
Modified: trunk/docs/user-manual/en/using-jms.xml
===================================================================
--- trunk/docs/user-manual/en/using-jms.xml 2010-01-07 13:25:20 UTC (rev 8767)
+++ trunk/docs/user-manual/en/using-jms.xml 2010-01-07 13:52:32 UTC (rev 8768)
@@ -21,7 +21,7 @@
<para>Although HornetQ provides a JMS agnostic messaging API, many users will
be more
comfortable using JMS.</para>
<para>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 following the<ulink
+ API. If you are completely new to JMS we suggest you follow the<ulink
url="http://java.sun.com/products/jms/tutorial/1_3_1-fcs/doc/jms_tut...
Sun
JMS tutorial</ulink> - a full JMS tutorial is out of scope for this
guide.</para>
<para>HornetQ also ships with a wide range of examples, many of which
demonstrate JMS API usage.
@@ -107,7 +107,8 @@
is the port used by the JNDI server and may vary depending on how you have
configured
your JNDI server.</para>
<para>In the default standalone configuration, JNDI server ports are
configured in the file
- <literal>hornetq-beans.xml</literal> by setting properties on
the <literal>JNDIServer</literal> bean:</para>
+ <literal>hornetq-beans.xml</literal> by setting properties on
the <literal
+ >JNDIServer</literal> bean:</para>
<programlisting>
<bean name="JNDIServer" class="org.jnp.server.Main">
<property name="namingInfo">
@@ -125,11 +126,11 @@
localhost</literal>!</para>
</note>
<note>
- <para>The JNDIServer bean must be defined <emphasis>only when
HornetQ is running in stand-alone mode</emphasis>.
- When HornetQ is integrated to JBoss Application Server, JBoss AS will
provide a ready-to-use
- JNDI server without any additional configuration.</para>
+ <para>The JNDIServer bean must be defined <emphasis>only when
HornetQ is running in
+ stand-alone mode</emphasis>. When HornetQ is integrated to
JBoss Application
+ Server, JBoss AS will provide a ready-to-use JNDI server without any
additional
+ configuration.</para>
</note>
-
</section>
<section>
<title>The code</title>
@@ -160,28 +161,38 @@
</programlisting>
<para>It's as simple as that. For a wide range of working JMS examples
please see the
examples directory in the distribution.</para>
+ <warning>
+ <para>Please note that JMS connections, sessions, producers and
consumers are
+ <emphasis>designed to be
re-used</emphasis>.</para>
+ <para>It's 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
+ <xref linkend="perf-tuning"/>.</para>
+ </warning>
</section>
<section>
<title>Directly instantiating JMS Resources without using
JNDI</title>
<para>Although it's a very common JMS usage pattern to lookup JMS
<emphasis>Administered
- Objects</emphasis> (that's JMS Queues, Topics and Connection
Factories) from JNDI,
- in some cases a JNDI server is not available and you still want to use JMS,
or you just
- think "Why do I need JNDI? Why can't I just instantiate these
objects directly?"</para>
+ Objects</emphasis> (that's JMS Queue, Topic and
ConnectionFactory instances) from
+ JNDI, in some cases a JNDI server is not available and you still want to use
JMS, or you
+ just think "Why do I need JNDI? Why can't I just instantiate these
objects
+ directly?"</para>
<para>With HornetQ you can do exactly that. HornetQ supports the direct
instantiation of JMS
- Queue, Topic and Connection Factory instances, so you don't have to use
JNDI at
+ Queue, Topic and ConnectionFactory instances, so you don't have to use
JNDI at
all.</para>
<para>For a full working example of direct instantiation please see the JMS
examples in
<xref linkend="examples"/>.</para>
<para>Here's our simple example, rewritten to not use JNDI at
all:</para>
- <para>We create the JMS ConnectionFactory object via the HornetQJMSClient
Utility class, note we need to provide
- connection parameters and specify which transport we are using, for more
information on
- connectors please see <xref
linkend="configuring-transports"/>.</para>
+ <para>We create the JMS ConnectionFactory object via the HornetQJMSClient
Utility class,
+ note we need to provide connection parameters and specify which transport we
are using,
+ for more information on connectors please see <xref
linkend="configuring-transports"
+ />.</para>
<programlisting>
TransportConfiguration transportConfiguration =
new TransportConfiguration(NettyConnectorFactory.class.getName());
ConnectionFactory cf = HornetQJMSClient.createConnectionFactory(transportConfiguration);
</programlisting>
- <para>We create the JMS Queue Object via the HornetQJMSClient Utility
class:</para>
+ <para>We also create the JMS Queue object via the HornetQJMSClient Utility
class:</para>
<programlisting>Queue orderQueue =
HornetQJMSClient.createQueue("OrderQueue");</programlisting>
<para>Next we create a JMS connection using the connection
factory:</para>
<programlisting>Connection connection =
cf.createConnection();</programlisting>
@@ -212,10 +223,10 @@
<section id="using-jms.dupsokbatchsize">
<title>Setting The Batch Size for DUPS_OK </title>
<para>When the JMS acknowledge mode is set to
<literal>DUPS_OK</literal> it is possible to
- configure the consumer so that it sends the acknowledgements in batches
rather that one
- at a time, saving valuable bandwidth. This can be configured via the
connection factory
- via the <literal>dups-ok-batch-size</literal> element and is set
in bytes. The default
- is 1024 * 1024 bytes = 1 MiB.</para>
+ 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 <literal>dups-ok-batch-size</literal> element and is set in
bytes. The default is
+ 1024 * 1024 bytes = 1 MiB.</para>
</section>
<section id="using-jms.txbatchsize">
<title>Setting The Transaction Batch Size</title>