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

后端 未结 3 1879
我在风中等你
我在风中等你 2021-02-06 10:57

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

相关标签:
3条回答
  • 2021-02-06 11:15

    For people who are hitting this exception

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

    even after following @Ualter Jr.'s answer is because of incorrect entries in the .bindings file.

    I corrected the following 2 lines in .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 just opened this class and found that it expects the following classnames

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

    Correcting these entries would enable existing/new JMS applications to work with RabbitMQ.

    0 讨论(0)
  • 2021-02-06 11:18

    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
    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:
    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");
    
    
    0 讨论(0)
  • 2021-02-06 11:26

    We can generate the .bindings file for RabbitMQ using below 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 讨论(0)
提交回复
热议问题