当前位置: 首页 > 知识库问答 >
问题:

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

文鸣
2023-03-14

我有一个通用的独立JMS应用程序,它与以下JMS提供程序一起工作WebSphere、HornetQ和ActiveMq。我传递上下文。INITIAL_CONTEXT_FACTORY和上下文。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提供程序,所以它没有初始上下文类或提供程序网址,但它提供了一个JMS客户端,这是它的Java客户端的抽象,符合JMS规范。RabbitMQ的JMS客户端留档有一个在JNDI中定义对象作为网络应用程序的一部分的资源配置的例子,但我完全不知道如何为我的独立应用程序做类似的事情,它使用JMS客户端的依赖关系创建基于JNDI提供程序的命名上下文,或者从可用的依赖关系中创建一个初始上下文。

那么,有人能解释一下如何做到这一点吗?希望我的问题清楚。

共有3个答案

庾才
2023-03-14

我们可以生成。使用以下java代码为RabbitMQ绑定文件:

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);
    }
傅献
2023-03-14

对于遇到此异常的人

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

即使是在遵循了@Ualt Jr.的答案之后,也是因为. 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

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

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

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

海典
2023-03-14

为了让JMS与RabbitMQ协同工作,必须启用插件RabbitMQ_JMS_topic_exchange
您可以按照本网站的说明下载(您需要登录):
https://my.vmware.com/web/vmware/details?downloadGroup=VFRMQ_JMS_105

  1. 提取后,将文件rjms-topic-selector-1.0.5.ez文件夹$RABBITMQ_SERVER\plugins中。
  2. 使用命令启用插件:Rabbitmq-plugins启用rabbitmq_jms_topic_exchange
  3. 使用以下命令检查插件是否运行正常:Rabbitmq-plugins html" target="_blank">list
    List of RabbitMQ plugins
  4. 重启RabbitMQ-我不确定是否真的有必要,但以防万一;-)
  5. 在RabbitMQ Web管理(http://localhost:15672/#/exchanges)中,您可以查看可用的新Exchange:Exchange of the RabbitMQ
  6. 现在,理论上:-),您已经能够使用标准JavaJMS 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

然后...最后...代码:


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

 类似资料:
  • 问题内容: 我在远程Glassfish服务器和计算机上的应用程序客户端中都有一个EJB模块。我想从应用程序客户端连接到远程EJB。 这是我的EJB接口: 这是我的ejb: 我有几个问题: 我可以在远程应用程序客户端中使用依赖注入来连接到ejb吗?如果是这样,我该怎么做才能做到这一点。我是否需要在sun-ejb-jar.xml和sun-application-client.xml中进行配置?换句话说

  • 我有一个wildfly域名,我需要连接。war部署了客户端项目,也部署了内部ejb模块服务。 这个域有两个服务器组,一个是8080端口中的appWeb项目,另一个是10080端口中的servMod,所以。 我有连接从本地网络与远程查找到jndi设置。 我部署的时候,细节已经出来了。webapp服务器组中的war文件与相同设置通信。 我不确定在本例中,我在提供者url中使用了“http远程处理”以及

  • 问题内容: 我对React还是很陌生,我正在开发一个应用程序,它将获取网页的实际屏幕截图,并且该应用程序可以在所截取的屏幕截图之上绘制并添加涂鸦。最初,我使用html2canvas和domToImage拍摄客户端屏幕快照,但它无法完全呈现网页中显示的图像。 Reddit用户/ pamblam0建议我调查Google的Puppeteer。它的工作方式是启动无头铬浏览器,该浏览器转到我在本地主机上的r

  • 问题内容: 有没有一种方法可以使用客户端(而不是Node.js)JavaScript直接连接到Redis? 我已经为一些项目成功使用了Node.js + PHP + Redis + Socket.io(用于客户端)。但是,我确实认为这可以进一步简化为类似PHP + Redis + Browser javascript的东西- 取出Node.js服务器,这是我不愿意使用的另一台服务器。对于简单的事情

  • 由于SSL配置错误,队列管理器jmsdemo无法用于客户端连接。 (AMQ4199)由于SSL 配置错误,队列管理器jmsdemo无法用于客户端连接。(AMQ4199)严重程度:30(严重错误)说明:用户正试图使用安全连接连接到远程队列管理器。响应:检查目标队列管理器和本地SSL信任存储区的SSL配置。 b)以下错误信息提取为“AMQERR01”错误文件(来自服务器端) 谢谢JK

  • 如何通过 JMX 客户端连接到 WebSphere JVM?是否可以使用 JMX 客户机连接到 WebSphere JVM 以更改日志记录设置?