通过 JMS 将 OpenLiberty 连接到 RabbitMQ

Connect OpenLiberty to RabbitMQ over JMS

我正在编写一个 Java EE 8 应用程序,我想将其连接到 RabbitMQ 总线。该应用程序部署在 OpenLiberty 中。由于应用程序使用 Java EE 8,我想使用 JMS 连接到 RabbitMQ。我之前有 connected to RabbitMQ over JMS in Tomcat 作为概念验证,所以我知道这一定是可能的。

根据我找到的文档和博客,我需要一个 资源适配器 来将 OpenLiberty 基本上连接到除其内部 JMS 引擎之外的所有其他内容。我找到了 AMQP 1.0 resource adapter 并想尝试一下。

我的server.xml:

<featureManager>
  <feature>beanValidation-2.0</feature>
  <feature>cdi-2.0</feature>
  <feature>jaxrs-2.1</feature>
  <feature>jsp-2.3</feature>
  <feature>servlet-4.0</feature>
  <feature>jms-2.0</feature>

  <feature>appSecurity-3.0</feature>
  <feature>socialLogin-1.0</feature>
</featureManager>

<!-- the resource-adapter-1.0.0.rar comes from the aforementioned GitHub project -->
<resourceAdapter id="amqp" location="${server.config.dir}/resource-adapter-1.0.0.rar">
  <classloader apiTypeVisibility="+third-party"/>
</resourceAdapter>

<jmsConnectionFactory jndiName="jms/JmsFactory">
  <!-- using .amqp as that is the ID for the resource adapter -->
  <properties.amqp ConnectionFactory=""
                   JndiParameters=""
                   DeleteTemporaryDestinations="true"
                   UserName=""
                   Password="" />
</jmsConnectionFactory>

然后,在我的应用程序代码中,我有

@Inject
@JMSConnectionFactory("jms/JmsFactory")
private JMSContext context;

只要我调用 context.createQueue("ExampleQueue")(或任何方法调用),我就会得到

javax.naming.NameNotFoundException: Intermediate context does not exist: jms/JmsFactory

我也尝试过手动查找,如下所示:

final InitialContext context = new InitialContext();
final Context environment = (Context) context.lookup("java:comp/env");

final QueueConnectionFactory factory = (QueueConnectionFactory) environment.lookup("jms/JmsFactory");
final Queue queue = InitialContext.doLookup("jms/ExampleQueue");

environment.lookup 处失败 javax.naming.NameNotFoundException: java:comp/env/jms/JmsFactory

我做错了什么,或者我在这里监督?

Liberty 期望 JMS 资源适配器的定义方式与该资源适配器定义自身的方式不匹配。 Liberty 期望 JMS 资源适配器使用 ra.xml 中的 JMS 类 作为接口定义,因此 javax.jms.ConnectionFactory。相反,此 RA 使用 org.jboss.resource.adapter.jms.JmsConnectionFactory。在运行时这是一个 javax.jms.ConnectionFactory,但在 ra.xml 中不是。

有一个简单的解决方法,只需使用 JCA connectionFactory 元素。我发现以下配置有效:

<connectionFactory jndiName="jms/JmsFactory">
   <!-- using .amqp as that is the ID for the resource adapter -->
   <properties.amqp DeleteTemporaryDestinations="true"
       ConnectionFactory="factory1"
       JndiParameters="java.naming.factory.initial=org.apache.qpid.jms.jndi.JmsInitialContextFactory;connectionFactory.factory1=amqp://localhost:5672"              
       UserName=""
       Password="" />
</connectionFactory>

Liberty 中存在针对此问题的错误 12088,但我建议仅使用 JCA connectionFactory 元素开始。