Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to connect to RabbitMQ using RabbitMQ JMS client from an existing JMS application?

Tags:

java

jms

rabbitmq

I have a generic standalone JMS application which works with following JMS providers WebSphere, HornetQ and ActiveMq. I pass Context.INITIAL_CONTEXT_FACTORY and Context.PROVIDER_URL as parameters to my application and create a naming context out of them by doing something like this

Properties environmentParameters = new Properties();
environmentParameters.put(Context.INITIAL_CONTEXT_FACTORY, property.context);
environmentParameters.put(Context.PROVIDER_URL, property.provider);
namingContext = new InitialContext(environmentParameters);

And use this context for object lookup.

I understand RabbitMQ isn't a JMS provider so it doesn't have an InitialContext class or a Provider URL but it provides a JMS Client which is an abstraction of its Java client conforming to JMS specification. RabbitMQ's JMS client documentation has an example of defining objects in JNDI as a resource configuration as part of a web application but I quite couldn't figure out how to do something similar for my standalone application which creates a naming context based on JNDI provider using JMS client's dependencies or to create an InitialContext out of the available dependencies.

So can someone throw some light on how this can be done? Hope my question is clear.

like image 268
Niranjan Subramanian Avatar asked Oct 28 '15 06:10

Niranjan Subramanian


People also ask

Can I use JMS with RabbitMQ?

Introduction. RabbitMQ is not a JMS provider but includes a plugin needed to support the JMS Queue and Topic messaging models. JMS Client for RabbitMQ implements the JMS 1.1 specification on top of the RabbitMQ Java client, thus allowing new and existing JMS applications to connect to RabbitMQ.

How do I connect to a JMS server?

You can connect to any JMS server by using the Java Naming and Directory Interface (JNDI) to locate an existing JMS connection factory. Depending on where the connection factory is bound, the connection URL can begin with the string lookup or the string jndi.

What is a JMS client?

The term “JMS client” refers to Java components or applications that use the JMS API and a JMS provider to send and receive messages. JMS supports two styles of messaging: the point−to−point and publis−and−subscribe messaging styles.


1 Answers

In order to get JMS working with RabbitMQ, you have to enable the plugin rabbitmq_jms_topic_exchange.
You can download it following the directions in this site (You'll need to login):
https://my.vmware.com/web/vmware/details?downloadGroup=VFRMQ_JMS_105&productId=349

  1. After extraction, put the file rjms-topic-selector-1.0.5.ez inside the Folder $RABBITMQ_SERVER\plugins.
  2. Enable the plugin with the command: rabbitmq-plugins enable rabbitmq_jms_topic_exchange
  3. Check if the plugin it's running ok with the command: rabbitmq-plugins list
    List of RabbitMQ plugins
  4. Restart the RabbitMQ - I'm not sure if it's really necessary, but just in case ;-)
  5. At your RabbitMQ web management (http://localhost:15672/#/exchanges) you can check the new Exchange you have available: Exchanges of the RabbitMQ
  6. Now, in theory :-), you're already able to connect to your RabbiMQ server using the standard Java JMS API.

Bear in mind that you'll have to create a .bindings file in order to JNDI found your registered objects. This is an example of the content of it:


    ConnectionFactory/ClassName=com.rabbitmq.jms.admin.RMQConnectionFactory
    ConnectionFactory/FactoryName=com.rabbitmq.jms.admin.RMQObjectFactory
    ConnectionFactory/RefAddr/0/Content=jms/ConnectionFactory
    ConnectionFactory/RefAddr/0/Type=name
    ConnectionFactory/RefAddr/0/Encoding=String
    ConnectionFactory/RefAddr/1/Content=javax.jms.ConnectionFactory
    ConnectionFactory/RefAddr/1/Type=type
    ConnectionFactory/RefAddr/1/Encoding=String
    ConnectionFactory/RefAddr/2/Content=com.rabbitmq.jms.admin.RMQObjectFactory
    ConnectionFactory/RefAddr/2/Type=factory
    ConnectionFactory/RefAddr/2/Encoding=String
    # Change this line accordingly if the broker is not at localhost
    ConnectionFactory/RefAddr/3/Content=localhost
    ConnectionFactory/RefAddr/3/Type=host
    ConnectionFactory/RefAddr/3/Encoding=String
    # HELLO Queue 
    HELLO/ClassName=com.rabbitmq.jms.admin.RMQDestination
    HELLO/FactoryName=com.rabbitmq.jms.admin.RMQObjectFactory
    HELLO/RefAddr/0/Content=jms/Queue
    HELLO/RefAddr/0/Type=name
    HELLO/RefAddr/0/Encoding=String
    HELLO/RefAddr/1/Content=javax.jms.Queue
    HELLO/RefAddr/1/Type=type
    HELLO/RefAddr/1/Encoding=String
    HELLO/RefAddr/2/Content=com.rabbitmq.jms.admin.RMQObjectFactory
    HELLO/RefAddr/2/Type=factory
    HELLO/RefAddr/2/Encoding=String
    HELLO/RefAddr/3/Content=HELLO
    HELLO/RefAddr/3/Type=destinationName
    HELLO/RefAddr/3/Encoding=String

And then... finally... the code:


    Properties environmentParameters = new Properties();
    environmentParameters.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
    environmentParameters.put(Context.PROVIDER_URL, "file:/C:/rabbitmq-bindings");
    namingContext = new InitialContext(environmentParameters);

    ConnectionFactory connFactory = (ConnectionFactory) ctx.lookup("ConnectionFactory");

like image 71
Ualter Jr. Avatar answered Oct 07 '22 12:10

Ualter Jr.