2

我正在尝试将 OpenLiberty 18.0.0.2 配置为使用嵌入式消息传递来发送一些简单的 JMS 消息。

我的当前server.xml如下所示:

<?xml version="1.0" encoding="UTF-8"?>

<server description="new server">
  <featureManager>
    <feature>javaee-8.0</feature>
    <feature>mpConfig-1.2</feature>
    <feature>mpMetrics-1.1</feature>
    <feature>wasJmsServer-1.0</feature>
    <feature>wasJmsClient-2.0</feature>
    <feature>localConnector-1.0</feature>
  </featureManager>
  <quickStartSecurity userName="admin" userPassword="adminpwd" />

  <httpEndpoint id="defaultHttpEndpoint" httpPort="9080" httpsPort="9443" />

  <applicationManager autoExpand="true" />
  <applicationMonitor updateTrigger="mbean" />

  <messagingEngine>
    <queue id="QUEUE1" />
  </messagingEngine>

  <jmsQueueConnectionFactory jndiName="jms/JmsFactory">
    <properties.wasJms remoteServerAddress="localhost:7276:BootStrapBasicMessaging" />
  </jmsQueueConnectionFactory>

  <jmsQueue jndiName="jms/JmsQueue">
    <properties.wasJms queueName="QUEUE1" />
  </jmsQueue>
</server>

我的 JMS 发件人如下所示:

public class JmsMessageSender {


    @Resource(mappedName = "jms/JmsFactory")
    private ConnectionFactory jmsFactory;

    @Resource(mappedName = "jms/JmsQueue")
    private Queue jmsQueue;

    public void send() {

        TextMessage message;

        try (Connection connection = jmsFactory.createConnection();
             Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
             MessageProducer producer = session.createProducer(jmsQueue)) {

            message = session.createTextMessage();
            message.setText("Hello World!");
            producer.send(message);

        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
}

当我运行我的应用程序时,当我尝试将消息发送到嵌入式消息队列时出现以下异常:

javax.jms.InvalidDestinationException: CWSIA0281E: The specified value null is not allowed for Destination.
[err]   at com.ibm.ws.sib.api.jms.impl.JmsDestinationImpl.checkNativeInstance(JmsDestinationImpl.java:993)
[err]   at [internal classes]

看起来我的代码无法通过JNDI. 我是否错误地配置了嵌入式消息传递或者是我的源代码中的错误?

更新 1

我更新了源代码,这样我就不会将目标传递给该.send()方法,现在我在启动时收到以下错误:

[ERROR   ] cdi.resource.injection.error.CWOWB1000E                                                                                                           
CWNEN0030E: The server was unable to obtain an object instance for the java:comp/env/de.rieckpil.blog.JmsMessageSender/jmsQueue reference.  
The exception message was: CWNEN1004E: The server was unable to find the de.rieckpil.blog.JmsMessageSender/jmsQueue default binding with the javax.jms.Queue type for the java:comp/env/de.rieckpil.blog.JmsMessageSender/jmsQueue reference.

更新 2:

现在可以发送消息,但我无法接收消息。我的消息驱动 bean 如下所示(该功能mdb-3.2已启用):

@MessageDriven(activationConfig = {
        @ActivationConfigProperty(propertyName = "destination",
                propertyValue = "jms/JmsQueue"),
        @ActivationConfigProperty(propertyName = "destinationType",
                propertyValue = "javax.jms.Queue")
})
public class JmsMessageReader implements MessageListener {

    @Override
    public void onMessage(Message message) {

        TextMessage textMessage = (TextMessage) message;
        try {
            System.out.println("Message arrived: " + textMessage.getText());
        } catch (JMSException e) {
            System.err.println(e.getMessage());
        }

    }
}
4

1 回答 1

3

编辑:评论后更新资源注入存在问题

首先,将 JMS API 使用修复为仅在目标中传递一次(而不是同时传递createProducer()send()。否则您可能会遇到CWSIA0066E失败。

二、将@Resource属性从mappedName改为lookup

这些变化反映在下面:

@Resource(lookup = "jms/JmsFactory")
private ConnectionFactory jmsFactory;

@Resource(lookup = "jms/JmsQueue")
private Queue jmsQueue;

public void send() {

    TextMessage message;

    try (Connection connection = jmsFactory.createConnection();
         Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
         MessageProducer producer = session.createProducer(jmsQueue)) {

        message = session.createTextMessage();
        message.setText("Hello World!");

        // Don't pass in destination again since you set it in createProducer()
        producer.send(message);   

        // ...

@Resource注射

最后,@Resource注入不会在任何旧的 POJO 中起作用,而只能在容器扫描的特殊类中起作用。尝试将注入移动到 servlet、EJB 或 CDI 托管 bean。

术语注释:

虽然我知道您为什么会想到将其称为“嵌入式 MQ”,但您在此处使用的“消息传递引擎”实际上是由Liberty 嵌入式消息传递提供的。

它也是一个 JMS 提供者。也就是说,它实现了 JMS API,MQ 也是 IBM 提供的另一个可以在 Liberty 中使用的 JMS 提供程序。

于 2018-08-15T18:27:52.137 回答