Thursday, July 5, 2012

Java Message Service API

Before learn about JMS API lets take a look at what is meant by messaging. Messaging is used to communicate among software component or software applications. A component should send the message to a destination and the recipient component can get the message from that destination. The communication done by messaging is loosely coupled and asynchronous. That is how messaging differs from remote method invocations and polling systems.

Now I'm going to explain what JMS API is by having a better understanding about messaging. Java Message Service API allows component or applications to create, send, receive and read messages. This API is designed by Sun and several partner companies. JMS API communication is loosely coupled and enable asynchronous and reliable (The JMS API can ensure that a message is delivered once and only once) communication service.

JMS consists with four main parts.
  • JMS provider -This implements the JMS interface and provides other administrative and control features
  • JMS client – programs or components written in Java. These can produce and consume messages.
  • Messages – These are communication objects
  • Administered Objects – These are preconfigured JMS objects created by an administrator for clients' usage. e.g. Destination and Connection Factories.

JMS API supports both
  • point to point – Use a queue and there is only one consumer
  • publish/subscribe message domains.
    • There can be multiple consumers
    • messages are based on topics
    • subscribers receive messages which were published after their subscription
    • subscribers must continue to be active in order to consume messages.(JMS API relaxes this timing dependency up to certain extend by allowing subscribers to create durable subscriptions, which receive messages sent while the subscribers are not active)

Version 1.1 of JMS API allows you to use the same code to both domains while message destination remains domain specific. the behavior of the application will depend in part on whether you are using a queue or a topic.

Message Consumption

JMS API provides both synchronous and asynchronous transitions.

  • Synchronous- Subscriber or the receiver explicitly fetches the message by calling the receive method. Receive method will wait until the message arrives or expires certain time limit.
  • Asynchronous- Client can register a message listener with a consumer.Whenever a message arrives at the destination, the JMS provider delivers the message by calling the listener's onMessage method, which acts on the contents of the message.

JMS Programming Components

  • Connection factory creates the connection
    • Connection factory is always a component of ConnectionFactory, QueueConnectionFactory or TopicConnectionFactory.
    • Connection provides an open TCP/IP connection between client and the provider.
  • connection creates the session.
    • One connection can create one or more sessions.
    • Session is a single threaded context to create and consume messages.
  • Session creates the Message Producer, Message Consumer and TextMessages.
  • Message producer creates the message and send it to the destination
  • Message consumer receive messages from the destination
    • receive method is used to receive messages synchronously.

In PTP destination is the queue.
In pub/sub destination is the topic.

How to run QPid WCF samples

 Recently I had to work in a project where I need to connect to Qpid server using a C# client. Before start the project I wanted to try out some samples in Qpid in order to get familiar with Qpid and WCF binding. There I had to face lot of difficulties since lack of gudelines provided by Qpid. Therefore I thought of writing down step by step guidlines to run Qpid WCF samples.

  • Download QPid from
  • Create an environment variable called QPID_ROOT for qpid base directory.(eg:C:\qpid\qpid-0.16)
  • Installl Visual Studio 2008.
  • Install Microsoft Visual Studio 2008 Service Pack 1
  • Install Boost 1.47.
    •     Go to the boost root directory.
    •     Run bootstrap.bat
    •     Run b2 toolset=msvc --build-type=complete stage -j<# cores>
  • Include the location of the Boost library (e.g. %BOOST_ROOT%\lib) in your PATH environment variable.
  • Create an environment variable called BOOST_ROOT for the root of the boost directory.
  • Install SDK 3.5.
  • Install NUnit.
  • Build Qpid cpp

    •     Build CMake.
    •     Build python
    •     Build Ruby.
    •     Ensure that all the build tools are available on your path(Eg:PATH=C:\python25;)
    •     From a command prompt:
      •     # cd qpid\cpp
      •     # cmake -i -G "Visual Studio 9 2008" 
    •     Go to \qpid-0.16\cpp. Open the qpid-cpp.sln solution, select Debug or Release, and build.


  • Create an environmentvariable called QPID_BUILD_ROOT and store the path to the Qpid build directory in it.(Eg:C:\qpid\qpid-0.16\cpp)
  • Open VS 2008 and build(by setting the platform target as x86)

 Building and executing samples


1.Copy the dlls Apache.Qpid.Channel.dll and Apache.Qpid.Interop.dll from %QPID_ROOT%\wcf\src\Apache\Qpid\Channel\bin\x86\Debug
  to the %QPID_ROOT%\wcf\samples\Channel\WCFToWCFDirect folder.

2.Build the solution WCFToWCFDirect.sln.(by setting the platform target as x86))

3.Copy qpidclientd.dll, qpidcommond.dll and qpidtypesd.dll from %QPID_ROOT%\cpp\src\Debug to bin\x86\Debug of each of the projects.
 These dlls are needed at runtime.

4.Copy qpidclientd.dll, qpidcommond.dll and qpidtypesd.dll to %QPID_ROOT%\wcf\tools\QCreate\Debug folder.

5.Start the qpid broker from the qpid build folder e.g. %QPID_ROOT%\cpp\src\Debug.
        command:qpidd.exe  qpidd.exe --data-dir=<to place where it need to be> --auth no
            (Eg:qpidd.exe --data-dir=C:\qpid\qpid-0.16\cpp\src\Debug auth no)

6.Create queue required using the QCreate tool located at
  %QPID_ROOT%\wcf\tools\QCreate\Debug. The syntax is QCreate %QPID_ROOT%. For
  this sample you should do

      QCreate routing_key message_queue
7. Start Service.exe from(Open the cmd as administrator)

8. Start Client.exe from