如何使用现有JMS应用程序中的RabbitMQ JMS客户端连接RabbitMQ?

我有一个通用的独立JMS应用程序,它与以下JMS提供程序WebSphere,HornetQ和ActiveMq一起使用。 我将Context.INITIAL_CONTEXT_FACTORY和Context.PROVIDER_URL作为参数传递给我的应用程序,并通过这样的操作创建一个命名上下文

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

并使用此上下文进行对象查找。

我理解RabbitMQ不是JMS提供者,因此它没有InitialContext类或Provider URL,但它提供了一个JMS Client,它是符合JMS规范的Java客户端的抽象。 RabbitMQ的JMS客户端文档有一个例子,它将JNDI中的对象定义为资源配置,作为Web应用程序的一部分,但我完全无法弄清楚如何为我的独立应用程序执行类似操作,该应用程序使用JMS基于JNDI提供程序创建命名上下文客户端的依赖关系或从可用的依赖关系中创建InitialContext。

那么有人可以说明如何做到这一点? 希望我的问题很清楚。

为了让JMS使用RabbitMQ ,您必须启用 插件rabbitmq_jms_topic_exchange
您可以按照本网站上的说明下载(您需要登录):
https://my.vmware.com/web/vmware/details?downloadGroup=VFRMQ_JMS_105&productId=349

  1. 解压缩后,将文件rjms-topic-selector-1.0.5.ez放在Folder $ RABBITMQ_SERVER \ plugins中。
  2. 使用以下命令启用插件: rabbitmq-plugins enable rabbitmq_jms_topic_exchange
  3. 使用以下命令检查插件是否正常运行: rabbitmq-plugins list
    RabbitMQ插件列表
  4. 重新启动RabbitMQ – 我不确定它是否真的有必要,但以防万一;-)
  5. 在您的RabbitMQ Web管理( http:// localhost:15672 /#/ exchange )中,您可以检查您可用的新Exchange: 交换RabbitMQ
  6. 现在,在理论上:-),您已经能够使用标准Java JMS API连接到您的RabbiMQ服务器。

请记住,您必须创建.bindings文件才能让JNDI找到您注册的对象。 这是它的内容的一个例子:

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 

然后……最后……代码:


    属性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”);

对于那些遇到此例外的人

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

即使在关注@Ualter Jr.后,答案也是因为.bindings文件中的条目不正确。

我在.bindings文件中更正了以下两行

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

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

当我再次遇到此exception时,我刚刚打开了这个类 ,发现它需要以下类名

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

更正这些条目将使现有/新的JMS应用程序能够与RabbitMQ一起使用。

我们可以使用以下java代码为RabbitMQ生成.bindings文件:

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