WARNING: This server provides a static reference view of the NetKernel documentation. Links to dynamic content do not work. For the best experience we recommend you install NetKernel and view the documentation in the live system .

Java Messaging Service (JMS) Connectivity

The module urn:org:ten60:netkernel:tpt:jms provides client and server mechanisms for sending and receiving messages from JMS queues and topics. The abstraction hides many of the complexities of the JMS API and as such may miss a small part of the functionality - the design of this library has been to provide a standard base which should be relatively easy to customize to a specific enterprise JMS configuration. However out of the box it provides the following functionality:

  • Send and receive from Queues
  • Publish and subscribe to Topics
  • Support for TextMessage and BytesMessage
  • Flexible JNDI InitialContext configuration
  • Full setting and getting of message properties and JMS headers
  • Dynamic configuration changes
  • Connection to multiple queues and topics concurrently
  • Message acknowledgement based on NetKernel service response, i.e. failure means no ack

Architecture

The JMS module consists of the following components:

  • A message driven transport which, when it receives a message, will issue the message as a NetKernel root request into the host fulcrum module's local address space.
  • A client accessor which can explicitly send messages to a queue or topic.
  • A JMS Message Broker connection representation and a transreptor to create a connection representation from an XML configuration - the configuration is dynamically polled which means the JMS environment can be dynamically updated with no down time.

Typically NetKernel will be configured to host message-driven-services which will be invoked by the JMS Transport. These services may then issue further messages to other queues or topics. However the choice of architecture will depend on the application - it would be equally as easy to have NetKernel as the primary driver of a message queue - generating JMS messages based upon some other transport-initiated-event such as a Web-application form submission or a SOAP or email message event occurring on another transport.

Configuration

A host fulcrum module should be created to host the JMS module and must provide an XML configuration and the actual mapped services which can handle the message requests generated by the JMS transport.

The configuration location defaults to res:/etc/JMSConfig.xml. A single XML configuration resource is used to configure both the JMS producer (accessor) and JMS consumer (transport)

Here is a commented example:


<!-- configuration for both producers and consumers of messages -->
<JMSProducer>
  <!-- a list of name value pairs to put into the InitialContext of JNDI -->
  <jndiContext>
    <java.naming.factory.initial> org.codehaus.activemq.jndi.ActiveMQInitialContextFactory </java.naming.factory.initial>
    <java.naming.provider.url>tcp://localhost:61616</java.naming.provider.url>
    <queue.MyQueue>example.MyQueue</queue.MyQueue>
    <topic.MyTopic>example.MyTopic</topic.MyTopic>
  </jndiContext>
  <!-- JNDI name of connection factory for Queues -->
  <queueConnectionFactory>QueueConnectionFactory</queueConnectionFactory>
  <!-- JNDI name of connection factory for Topics -->
  <topicConnectionFactory>TopicConnectionFactory</topicConnectionFactory>
  <!-- a set of queue and topic declarations -->
  <!-- a queue declaration -->
  <queue>
    <!-- logical JNDI name of Queue -->
    <name>MyQueue</name>
    <!-- BytesMessage and TextMessage are supported (only used by producer) -->
    <messageType>BytesMessage</messageType>
    <!-- if true and acknowledgement is always given, if false only when no exception (only used by consumer) -->
    <ackOnException>false</ackOnException>
  </queue>
  <!-- a topic declaration -->
  <topic>
    <!-- logical JNDI name of Topic -->
    <name>MyTopic</name>
    <messageType>BytesMessage</messageType>
    <ackOnException>false</ackOnException>
    <!-- an optional standard message selector string -->
    <messageSelector>ContentType = 'content/unknown'</messageSelector>
  </topic>
</JMSProducer>

Example

See the tutorial.

ClassPath

The JMS module is built against the jms-1.1 javax.jms package library however it ships with no specific implementation. You will need to place the jar files for your specific implementation in the /lib directory of the fulcrum or application module which imports the JMS module.

Native Libraries

Some JMS implementations - such as IBM MQ - also require access from the JVM to native libraries (on *nix file extension .so). You can instruct the JVM where to find native libraries with the following java command line argument:

  • Djava.library.path=/usr/lib

/usr/lib is typical for *nix platforms but you may specify a different path.

Receiving Messages

The JMS transport can be used to subscribe to JMS topics and to retrieve messages from queues. For details about configuration and use see the JMS Transport Guide.

Sending Messages

There are two methods to send a message to a queue or topic, firstly by SINKing to a queue or topic URI, and secondly, by using the active:jms-send service.

Sinking to Queue/Topic

The simplest way to send a message to a queue or topic is to sink to its URI, which is either jms-queue:[logical JNDI queue name] or jms-topic:[logical JNDI topic name]. If you send a message this way you have no control on the JMS header and property fields. The type of message sent will depend upon the configuration. If a TextMessage is specified, the supplied resource will be transrepted (if necessary) to a java.lang.String. If a BytesMessage is specified, the supplied resource will be transrepted to an org.netkernel.layer0.representation.IReadableBinaryStreamRepresentation.

jms-send Service

To gain full control over the message to be sent the jms-send service can be used. For full details see the active:jms-send accessor reference.

Compatibility

The JMS connectivity module uses standard JMS APIs and should be compatible with all JMS implementations. It has been tested with Active MQ.

Here is a guide to configuring JMS to work with IBM MQ.

Customizing / Rebuilding

You may want to customize the JMS components for your JMS system, for example for domain specific security considerations, or rebuild the library against your JMS implementations libraries.

The source is provided in the JMS module - to build you must link against the core NetKernel libraries.

You must also link against your JMS library's implementation of the javax.jms.* packages.

Troubleshooting

JMS implementations vary greatly from vendor to vendor. Here are some common issues you may encounter:

  • JNDI ClassCastException on JNDI lookup of Queue/TopicConnectionFactory ensure that your vendor supplied JMS jar libraries are located in the /lib/ directory
  • javax.jms.XXXXX ClassCastException the JMS library is built against the apache geronima javax.jms.* packages. Rebuild the tpt-jms module against your vendor supplied javax.jms libraries.

Still having trouble - please contact 1060 Research for expert assistance with integrating your vendor's JMS implementation.