Как настроить OpenLiberty 18.0.0.2 для использования встроенного обмена сообщениями Liberty?

Я пытаюсь настроить 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());
        }

    }
}

person rieckpil    schedule 15.08.2018    source источник


Ответы (1)


EDIT: обновление после комментария о том, что возникла проблема с внедрением ресурсов.

Во-первых, исправьте использование 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, а только в специальных классах, которые сканируются контейнером. Попробуйте переместить внедрение в сервлет, EJB или управляемый компонент CDI.

Примечание по терминологии:

Хотя я понимаю, почему вы решили назвать этот встроенный MQ, механизм обмена сообщениями, который вы здесь используете, предоставляется тем, что на самом деле называется Встроенный обмен сообщениями Liber.

Это также поставщик JMS. То есть он реализует JMS API, как и MQ, другой поставщик JMS, предоставляемый IBM, который можно использовать в Liberty.

person Scott Kurz    schedule 15.08.2018
comment
Спасибо за вашу помощь. Я обновил кодовую базу в вопросе и попробовал вашу модификацию. Теперь я получаю другую ошибку: CWOWB1000E - person rieckpil; 16.08.2018
comment
Хорошо, я реорганизовал ответ, так как у вас может быть проблема с инъекцией. - person Scott Kurz; 16.08.2018
comment
спасибо, теперь мой отправитель JMS работает. Теперь у меня проблемы с получением сообщения в bean-компоненте, управляемом сообщениями. На моем сервере включена функция mdb-3.2, но я не получаю никаких данных. Я обновил вопрос для простого bean-компонента, управляемого сообщениями. - person rieckpil; 17.08.2018
comment
Я понимаю, что это всего лишь пример вашей попытки, но часть MDB кажется более подходящей для того, чтобы выделить ее в отдельный вопрос. - person Scott Kurz; 17.08.2018
comment
Вероятно, вам нужно настроить активациюSpec для MDB. - person Scott Kurz; 18.08.2018
comment
Хорошо, спасибо за вашу поддержку. Я попробую активациюSpec и открою новый вопрос, если мне понадобится помощь: D - person rieckpil; 18.08.2018