如何配置 OpenLiberty 18.0.0.2 以使用 Liberty 嵌入式消息传递?
How to configure OpenLiberty 18.0.0.2 to use Liberty embedded messaging?
我正在尝试将 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());
}
}
}
编辑:评论资源注入存在问题后更新
首先,修复 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 embedded messaging.
提供的
它也是一个 JMS 提供程序。也就是说,它实现了 JMS API,MQ 也是如此,后者是 IBM 提供的另一个可在 Liberty 中使用的 JMS 提供程序。
我正在尝试将 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());
}
}
}
编辑:评论资源注入存在问题后更新
首先,修复 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 embedded messaging.
提供的它也是一个 JMS 提供程序。也就是说,它实现了 JMS API,MQ 也是如此,后者是 IBM 提供的另一个可在 Liberty 中使用的 JMS 提供程序。