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

I have a separate standalone JMS application that works with the following WebSphere, HornetQ, and ActiveMq JMS providers. I pass Context.INITIAL_CONTEXT_FACTORY and Context.PROVIDER_URL as parameters for my application and create a naming context from them, 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 to search for objects.

I understand that RabbitMQ is not a JMS provider, so it does not have the InitialContext class or the provider URL, but it provides a JMS client, which is an abstraction of its Java client that complies with the JMS specification. The RabbitMQ JMS client documentation contains an example of defining objects in JNDI as a resource configuration as part of a web application, but I absolutely could not figure out how to do something like this for my standalone application, which creates a naming context based on the JNDI provider using JMS client dependencies, or to create an InitialContext from available dependencies.

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

+5
source share
3 answers

For people who fall into this exception

 Caused by: javax.naming.NamingException: Unknown class [com.rabbitmq.jms.admin.RMQConnectionFactory] 

even after the following answer by @Ualter Jr. due to invalid entries in the .bindings file.

I fixed the following 2 lines in the .bindings file

 ConnectionFactory/ClassName=com.rabbitmq.jms.admin.RMQConnectionFactory ---> ConnectionFactory/ClassName=javax.jms.ConnectionFactory 

and

 YourQueueName/ClassName=com.rabbitmq.jms.admin.RMQDestination ---> StriimQueue/ClassName=javax.jms.Queue 

When I hit this exception again, I simply opened this class and found that it was expecting the following cool names

  /* * Valid class names are: * javax.jms.ConnectionFactory * javax.jms.QueueConnectionFactory * javax.jms.TopicConnectionFactory * javax.jms.Topic * javax.jms.Queue * */ 

Correcting these entries will allow you to use existing / new JMS applications to work with RabbitMQ.

+2
source

To get the RabbitMQ - enabled JMS , you must enable the rabbitmq_jms_topic_exchange plugin.
You can download it using the signs on this site (you will need to log in):
https://my.vmware.com/web/vmware/details?downloadGroup=VFRMQ_JMS_105&productId=349

  • After extracting, place the rjms-topic-selector-1.0.5.ez file inside the $ RABBITMQ_SERVER \ folders.
  • Enable the plugin with the command: rabbitmq-plugins enable rabbitmq_jms_topic_exchange
  • Check if the plugin works with the command: rabbitmq-plugins list
    List of RabbitMQ plugins
  • Reboot RabbitMQ - I'm not sure if this is really necessary, but just in case; -)
  • In your RabbitMQ web control ( http: // localhost: 15672 / # / exchanges ) you can check out the new Exchange that you have: Exchanges RabbitMQ
  • Now, theoretically :-), you can already connect to your RabbiMQ server using the standard Java JMS API.

Keep in mind that you will need to create a .bindings file so that JNDI detects your registered objects. This is an example of its contents:

 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
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");

+7
source

We can generate the .bindings file for RabbitMQ using the following java code: import java.util.Properties;

 import javax.jms.ConnectionFactory; import javax.jms.Queue; import javax.jms.Topic; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.Reference; import javax.naming.StringRefAddr; Properties env = new Properties(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory"); env.put(Context.PROVIDER_URL, "file:bindings"); Context ctx = new InitialContext(env); Reference connectionFactoryRef = new Reference(ConnectionFactory.class.getName(), RMQObjectFactory.class.getName(), null); connectionFactoryRef.add(new StringRefAddr("name", "jms/ConnectionFactory")); connectionFactoryRef.add(new StringRefAddr("type", ConnectionFactory.class.getName())); connectionFactoryRef.add(new StringRefAddr("factory", RMQObjectFactory.class.getName())); connectionFactoryRef.add(new StringRefAddr("host", "$JMS_RABBITMQ_HOST$")); connectionFactoryRef.add(new StringRefAddr("port", "$JMS_RABBITMQ_PORT$")); ctx.rebind("ConnectionFactory", connectionFactoryRef); String jndiAppend = "jndi"; for (int i = 1; i <= 10; i++) { String name = String.format("queue%02d", i); Reference ref = new Reference(Queue.class.getName(), com.rabbitmq.jms.admin.RMQObjectFactory.class.getName(), null); ref.add(new StringRefAddr("name", "jms/Queue")); ref.add(new StringRefAddr("type", Queue.class.getName())); ref.add(new StringRefAddr("factory", RMQObjectFactory.class.getName())); ref.add(new StringRefAddr("destinationName", name)); ctx.rebind(name+jndiAppend, ref); name = String.format("topic%02d", i); ref = new Reference(Topic.class.getName(), com.rabbitmq.jms.admin.RMQObjectFactory.class.getName(), null); ref.add(new StringRefAddr("name", "jms/Topic")); ref.add(new StringRefAddr("type", Topic.class.getName())); ref.add(new StringRefAddr("factory", RMQObjectFactory.class.getName())); ref.add(new StringRefAddr("destinationName", name)); ctx.rebind(name+jndiAppend, ref); } 
0
source

Source: https://habr.com/ru/post/1234664/


All Articles