Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3
Info

This page is out of date and should not be used. Please refer to the Qpid JMS client books for up to date documentation.

How to use

...

the PropertiesFileInitialContextFactory

This ContextFactory uses a java properties formatted file to setup initial values.This is the example properties file

JNDI Property setup

By setting the JNDI Initial Context Factory and URL as below it is possible to load any File from the locally mounted file system to use for JNDI purposes. The format of the file is described in the next section.

No Format

java.naming.factory.initial = org.apache.qpid.jndi.PropertiesFileInitialContextFactory
java.naming.provider.url = <path to JNDI File>

By simply setting these two system properties you can jump straight to the InitialContext creation in your code.

Example properties file

This is the example properties file.

No Format
PropertiesFileInitialConextFactory

# use the following property to configure the default connector
#java.naming.provider.url - ignored.

# register some connection factories
# connectionfactory.[jndiname] = [ConnectionURL]
connectionfactory.local = amqp://guest:guest@clientid/testpath?brokerlist='vm://:1'

# register some queues in JNDI using the form
# queue.[jndiName] = [physicalName]
queue.MyQueue = example.MyQueue

# register some topics in JNDI using the form
# topic.[jndiName] = [physicalName]
topic.ibmStocks = stocks.nyse.ibm

# Register an AMQP destination in JNDI
#   NOTE: Qpid currently only supports direct,topics and headers
# destination.[jniName] = [BindingURL]
destination.direct = direct://amq.direct//directQueue

The property file allows a number of queues to be defined that can then be discovered via JNDI. There are four properties used by the PFICFactory.
connectionfactory.<jndiname> this is the Connection URL that the connection factory will use to perform connections.
queue.<jndiname> this defines a jms queue or in amqp a amq.direct exchange
topic.<jndiname> this defines a jms topic or in amqp a amq.topic exchange
destination.<jndiname> this takes a Binding URL and so can be used for defining all amq destinations, queues, topics and header matching.

...

NOTE: This does not create the destination queue on the broker. In AMQP destinations only exist once a consumer has connected to that resource. You should ensure that you have created the destination queue before publishing to it. Queues can be declared in the virtualhosts.xml file so that they are created on broker startup, or created dynamically by consuming clients. Topics and other destinations that use temporary queues cannot be created in this way, so a consumer must be created first before publishing messages with mandatory routing.

Example lookup code

The bindingValue is the String that would be placed in <jndiname> above.

Code Block
titleSimple JNDI lookup using files
borderStylesolid

//Ensure Loadyou thehave propertiesyour filesystem ...properties set
Properties properties = new Properties();
properties.load(propertiesfile_inputStreamfinal String INITIAL_CONTEXT_FACTORY = "org.apache.qpid.jndi.PropertiesFileInitialContextFactory";

System.setProperty(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
System.setProperty(Context.PROVIDER_URL, _JNDIFile);

// Create the initial context
Context ctx = new InitialContext(properties);

// Perform the binds
object = ctx.lookup(bindingValue);

// Close the context when we're done
ctx.close();

How to use a JNDI Provider

Qpid will work with any JNDI provider capable of storing Java objects. We have a task to add our own initial context factory, but until that's available ....

First you must select a JNDI provider to use. If you aren't already using an application server (i.e. Tomcat ?) which provides JNDI support you could consider using either:

...

  • Click : Download JNDI 1.2.1 & More button
  • Download: File System Service Provider, 1.2 Beta 3
  • and then add the two jars in the lib dir to your class path.

There are two steps to using JNDI objects.

  • Bind : Which stores a reference to a JMS Object in the provider.
  • Lookup : Which tries to retrieve the reference and create the JMS Object.

There are two objects that would normally be stored in JNDI.

  • A ConnectionFactory
  • A Destination (Queue or Topic)

Binding

Then you need to setup the values that the JNDI provider will used to bind your references, something like this:

Code Block
titleSetup Simple JNDI lookup using properties
borderStylesolid

Hashtable env = new Hashtable(11);
  env.put(Context.final String INITIAL_CONTEXT_FACTORY,"com.sun = "org.apache.qpid.jndi.fscontext.RefFSContextFactoryPropertiesFileInitialContextFactory");

final  env.put(Context.PROVIDER_URL,LOCAL_FILE_PATH_FOR_STORING_BINDS_PATH_MUST_EXIST);

These values are then used to create a context to bind your references.

Code Block
titlePerform Binding of ConnectionFactory
borderStylesolid

try
{
    Context ctx = new InitialContext(env);

    // Create the object to be bound in this case a ConnectionFactory
    ConnectionFactory factory = null;

    try
    {
        factory = new AMQConnectionFactory(CONNECTION_URL);
        try
        {
            ctx.bind(binding, factory);
        }
        catch (NamingException e)
        {
            //Handle problems with binding. Such as the binding already exists.
        }
    }
    catch (URLSyntaxException amqe)
    {
        //Handle any exception with creating ConnnectionFactory
    }
}
catch (NamingException e)
{
    //Handle problem creating the Context.
}

To bind a queue instead simply create a AMQQueue object and use that in the binding call.

Code Block
titleBind a AMQQueue
borderStylesolid

AMQQueue  queue = new AMQQueue(QUEUE_URL);
ctx.bind(binding, queue);

Lookup

You can then get a queue connection factory from the JNDI context.

Code Block
titlePerform Binding of ConnectionFactory
borderStylesolid

ConnectionFactory factory;
try
{
    factory= (ConnectionFactory)ctx.lookup(binding);
}
catch (NamingException e)
{
    //Handle problems with lookup. Such as binding does not exist.
}

Note that you need not cast the bound object back to an AMQConnectionFactory so all your current JMS apps that use JNDI can start using Qpid straight away.

How to create a TopicConnectionFactory and QueueConnectionFactory

String CONNECTION_JNDI_NAME = "local";
final String CONNECTION_NAME = "amqp://guest:guest@clientid/testpath?brokerlist='vm://:1'";

final String QUEUE_JNDI_NAME = "queue";
final String QUEUE_NAME = "example.MyQueue";

// Set the properties ... 
Properties properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
properties.put("connectionfactory."+CONNECTION_JNDI_NAME , CONNECTION_NAME);
properties.put("queue."+QUEUE_JNDI_NAME , QUEUE_NAME);

// Create the initial context
Context ctx = new InitialContext(properties);

// Perform the lookups
ConnectionFactory factory = (ConnectionFactory)ctx.lookup(CONNECTION_JNDI_NAME);
Queue queue = (Queue)ctx.lookup(QUEUE_JNDI_NAME);

// Close the context when we're done
ctx.close();

Using Qpid with other JNDI ProvidersAMQConnectionFactory implements TopicConnectionFactory and QueueConnectionFactory as well as the ConnectionFactory.