Skip to main content
Skip table of contents

JNDI Client

Federated JNDI Context

Overview

The Federated JNDI Context is the default built-in JNDI context that directly communicates with the JNDI Swiftlet of the connected SwiftMQ Router.

InitialContextFactory Class Name

JNDI uses a factory pattern to create a vendor-specific implementation of InitialContext. The name of the provider's implementation of this InitialContextFactory must be set in an environment table before creating an InitialContext object. The name of SwiftMQ's InitialContextFactory implementation is:

com.swiftmq.jndi.InitialContextFactoryImpl

JNDI Provider URL

The JNDI provider URL is used to set up the internal connection properties. A JNDI connection is internally backed up by a JMS connection. Hereby, any available JMS inbound listener can be used. For details please have a look at the JMS Swiftlet configuration.

The JNDI provider URL specifies the properties of the underlying JMS connection with the following format:

CODE
smqp://[<user>[:<password>]@](<host>:<port>)|"intravm"[/[host2=<host2>][;port2=<port2>]
        [;reconnect=<boolean>][;retrydelay=<long>][;maxretries=<int>][;type=<type>]
        [;timeout=<long>][;keepalive=<long>][;debug=<boolean>][;idleclose=<long>]

Where

CODE
smqp       ::=  Specifies the SwiftMQ Protocol
<user>     ::=  Username. Default is 'anonymous'
<password> ::=  User's password. Default is null.
<host>     ::=  DNS hostname of the 1st HA instance or the keyword "intravm" to connect intra-VM
<port>     ::=  JMS listener port of the 1st HA instance
host2      ::=  DNS hostname of the 2nd HA instance
port2      ::=  JMS listener port of the 2nd HA instance
reconnect  ::=  Specifies whether an automatic reconnect should be done
retrydelay ::=  Amount in milliseconds to wait between reconnect retries
maxretries ::=  Max. number of reconnect retries
type       ::=  Class name of the socket factory used by this JMS listener.
               In this release, com.swifmq.net.PlainSocketFactory and
               com.swiftmq.net.JSSESocketFactory are available. Default is
               com.swifmq.net.PlainSocketFactory. See JMS Swiftlet configuration for details.
timeout    ::=  Specifies a timeout in milliseconds for lookups. If no JNDI object is
               received within this time, the lookup throws a NamingException. Default is no timeout;
               lookups are waiting until they receive the requested JNDI objects.
keepalive  ::=  Specifies a keepalive interval in milliseconds. If this value is greater 0, a
               timer is created on the client side to send keepalive messages to detect broken
               JNDI connections. Default is 60000 (1 minute)
debug      ::=  If true, debug information are printed to System.out. Good for testing.
idleclose  ::=  Specifies the maximum idle time of the underlying JMS connection after which it is
                closed. It is re-opened when the context is accessed again (i.e. a new lookup).
                Default is 60000 ms. To disable it, set it to -1.

Note: Attributes "host2" and "port2" are reserved when connected to a SwiftMQ HA Router.

Examples

JNDI lookups should be performed via a JMS listener on host localhost, port 4001, as user anonymous. The JMS listener provides access via a com.swiftmq.net.PlainSocketFactory. No lookup timeout should be set:

CODE
    smqp://locahost:4001

JNDI lookups should be performed via a JMS listener on host www.swiftmq.com, port 4020, as user johnsmith, password ballaballa. The JMS inbound listener provides access via a com.swiftmq.net.JSSESocketFactory. The lookup timeout should be set to 20 secs:

CODE
    smqp://johnsmith:ballaballa@www.swiftmq.com:4020/type=com.swiftmq.net.JSSESocketFactory;timeout=20000

Connects to host jms1 at port 4001. If a connection loss is detected, it reconnects with a delay of 1 second between retries. It stops retries after 50 unsuccessful attempts. JNDI lookup timeout is set to 10 seconds.

CODE
    smqp://jms1:4001/timeout=10000;reconnect=true;retrydelay=1000;maxretries=50

Performing JNDI Lookups

To use JNDI, the following import statement has to be included into the application's import list:

JAVA
        import javax.naming.*;

Furthermore, the JNDI and the SwiftMQ classes must be accessible through the CLASSPATH.

Before creating an InitalContext object, two environment properties must be set. These are the names of the InitialContextFactory implementation and the SwiftMQ JNDI-Provider-URL:

JAVA
        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY,"com.swiftmq.jndi.InitialContextFactoryImpl");
        env.put(Context.PROVIDER_URL,"smqp://localhost:4001");

Then, the InitialContext is to be created:

JAVA
        InitialContext ctx = new InitialContext(env);

Now, a JNDI connection has been established and lookups can be performed to fetch the appropriate administered objects:

JAVA
        TopicConnectionFactory tcf = (TopicConnectionFactory)ctx.lookup("plainsocket@router3");
        Topic topic = (Topic)ctx.lookup("iit.projects.swiftmq");
        // etc pp

Bind/Rebind/Unbind

A JMS client that has created a TemporaryTopic or a TemporaryQueue can register this kind of object within SwiftMQ's JNDI implementation. It is not permitted to register other types of objects. After registration, other JMS clients are able to look up these objects under their registered names. This is a rare case because the TopicRequestor resp does the normal handling of this issue. QueueRequestorhelper classes. Here, the temporary destination is set in the message by the message producer as a JMSReplyTo header. The receiver/subscriber gets this destination and replies to it. In special cases, this procedure is not possible. For these cases, the destinations could be registered within JNDI.

To register a temporary destination, use Context.bind:

JAVA
        TemporaryQueue tq = queueSession.createTemporaryQueue();
        ctx.bind("myTempQueue",tq);

Another client is able to lookup this object and send messages to it:

JAVA
        TemporaryQueue tq = ctx.lookup("myTempQueue");
        QueueSender sender = queueSession.createQueueSender(tq);
        sender.send(msg);

A client can also change an existing registration with Context.rebind:

JAVA
        ctx.rebind("myInboundQueue",tq);

And, of course, it can remove the registration with:

JAVA
        ctx.unbind("myInboundQueue");

JNDI registrations of temporary destinations have a lifetime of the temporary destination itself. If the temporary destination will be deleted by the client, for example with tq.delete(), or the JMS connection that has created the temporary destination will be closed (which deletes implicitly their temporary destinations), all JNDI registrations of these destinations will also be deleted automatically. So, a client does not need to explicitly call unbind for his registrations.

Closing the Context

By closing the InitialContext, the connection is dropped and all resources on the client and server side are released. Otherwise, the client may not terminate, because there are running threads.

Idle Close (since 12.4.1)

The InitialContext is backed by an internal JMS connection which is closed after reaching an idle timeout. It is re-opened when new access, i.e. a lookup, takes place. The default idle timeout is 60000 ms and can be set via the URL attribute idleclose. It can be disabled by setting it to -1. It is recommended to stick with the default setting since it is often forgotten to close the InitialContext resulting in unused JMS connections.

Filesystem JNDI Context

Overview

The Filesystem JNDI Context is a built-in filesystem-based JNDI context which uses a directory at the client to store and lookup JNDI objects.

InitialContextFactory Class Name

JNDI uses a factory pattern to create a vendor-specific implementation of InitialContext. The name of the provider's implementation of this InitialContextFactory must be set in an environment table before creating an InitialContext object. The name of SwiftMQ's filesystem-based InitialContextFactoryimplementation is com.swiftmq.jndi.fs.InitialContextFactoryImpl.

JNDI Provider URL

The JNDI provider URL is a file URL and must point to the directory where the JNDI objects are stored.

Example:

file:///home/test/myjndi

Storing JNDI Objects

There are 2 ways to store JNDI objects in the directory where the JNDI provider URL points to:

  • By JNDI replication

  • By manual creation

JNDI replication can be set up in the JNDI Swiftlet by using the JNDI properties described for the JNDI lookup, see below. It dumps all registered JNDI objects to the directory specified by the JNDI provider URL. This directory then can be transferred to the clients to perform the lookups.

The other way is the manual creation of the JNDI objects. SwiftMQ uses XStream for JNDI object serialization. There are 3 types of administered objects that can be stored: Connection factories, queues, and topics. JNDI objects are stored one file per object with the lookup name as the file name plus a ".xml" extension like "ConnectionFactory.xml".

Connection Factories

Various attributes can be defined. Have a look at the JMS Swiftlet for its meanings. Here is an example, stored in file "ConnectionFactory.xml", of a connection factory that was dumped in a JNDI replication:

XML
   <com.swiftmq.jms.v750.ConnectionFactoryImpl>
     <listenerName>plainsocket</listenerName>
     <socketFactoryClass>com.swiftmq.net.PlainSocketFactory</socketFactoryClass>
     <hostname>imac-buero</hostname>
     <port>4001</port>
     <keepaliveInterval>60000</keepaliveInterval>
     <smqpProducerReplyInterval>20</smqpProducerReplyInterval>
     <smqpConsumerCacheSize>500</smqpConsumerCacheSize>
     <smqpConsumerCacheSizeKB>2048</smqpConsumerCacheSizeKB>
     <jmsDeliveryMode>2</jmsDeliveryMode>
     <jmsPriority>4</jmsPriority>
     <jmsTTL>0</jmsTTL>
     <jmsMessageIdEnabled>true</jmsMessageIdEnabled>
     <jmsMessageTimestampEnabled>true</jmsMessageTimestampEnabled>
     <useThreadContextCL>false</useThreadContextCL>
     <inputBufferSize>131072</inputBufferSize>
     <inputExtendSize>65536</inputExtendSize>
     <outputBufferSize>131072</outputBufferSize>
     <outputExtendSize>65536</outputExtendSize>
     <intraVM>false</intraVM>
     <port2>-1</port2>
     <reconnectEnabled>true</reconnectEnabled>
     <maxRetries>50</maxRetries>
     <retryDelay>10000</retryDelay>
     <duplicateMessageDetection>true</duplicateMessageDetection>
     <duplicateBacklogSize>30000</duplicateBacklogSize>
   </com.swiftmq.jms.v750.ConnectionFactoryImpl>

Queues

An example, stored in file "testqueue@router1.xml", of a queue that was dumped in a JNDI replication (Attribute s is the name of the queue):

XML
    <com.swiftmq.jms.QueueImpl>
      <queueName>
        <s>testqueue@router1</s>
      </queueName>
    </com.swiftmq.jms.QueueImpl>

Topics

An example, stored in file "testtopic.xml", of a queue that was dumped in a JNDI replication (Attribute s is the name of the topic):

XML
    <com.swiftmq.jms.TopicImpl>
      <topicName>
        <s>testtopic</s>
      </topicName>
    </com.swiftmq.jms.TopicImpl>

Performing JNDI Lookups

To use JNDI, the following import statement has to be included in the application's import list:

JAVA
        import javax.naming.*;

Furthermore, the JNDI and the SwiftMQ classes must be accessible through the CLASSPATH.

Before creating an InitalContext object, two environment properties must be set. These are the names of the InitialContextFactory implementation and the JNDI-Provider-URL:

JAVA
        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY,"com.swiftmq.jndi.fs.InitialContextFactoryImpl");
        env.put(Context.PROVIDER_URL,"file:///path/to/localjndi");

Then, the InitialContext is to be created:

JAVA
        InitialContext ctx = new InitialContext(env);

Now lookups can be performed to fetch the JNDI objects:

JAVA
        TopicConnectionFactory tcf = (TopicConnectionFactory)ctx.lookup("plainsocket@router3");
        Topic topic = (Topic)ctx.lookup("iit.projects.swiftmq");
        // etc pp

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.