保险丝卡拉夫保险丝-karaf-7.11.1.fuse-7_11_1-00013-redhat-00003。
我正在使用 AMQP 协议创建一个从 servlet 到 ActiveMQ“Classic”5.9 的简单桥梁。我成功配置了 JMS
ConectionFactory
并使用 jms:send
命令测试正常。我编写了一个 JMS 服务,该服务从 servlet 端响应 POST,但无法创建连接工厂。
admin@root()> jms:connectionFactories
JMS Connection Factory
----------------------
jms/artemis
Jms服务代码为:
package com.mycompany.jms;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TemporaryQueue;
import javax.jms.TextMessage;
import javax.naming.*;
import org.apache.aries.blueprint.annotation.service.Reference;
import org.apache.aries.blueprint.annotation.service.Service;
import org.apache.aries.blueprint.annotation.service.ServiceProperty;
import com.mycompany.JmsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Service(classes = JmsService.class, properties = {
// Only necessary for Remote Services
@ServiceProperty(name = "service.exported.interfaces", values = "*") })
@Singleton
public class JmsService4Reals implements JmsService {
private static final Logger LOG = LoggerFactory.getLogger(JmsService4Reals.class);
@Reference
ConnectionFactory connectionFactory;
@Override
public String sendMessage(String opeCod, String message) {
LOG.info(String.format("received: opeCod=%s, msg=%s", opeCod, message));
try {
if(connectionFactory== null)
return "Reference: no connectionFactory found";
Connection connection = null;
try {
connection = connectionFactory.createConnection();
LOG.info("JMS Connection created=%s", connection);
connection.start();
} catch (JMSException e) {
if (connection != null)
connection.stop();
return prepareErrorResponse(e.getMessage());
}
} catch (JMSException e) {
return prepareErrorResponse(e.getMessage());
}
}
private String prepareErrorResponse(String msg) {
return msg;
}
}
servlet 总是响应
Reference: no connectionFactory found
我也尝试过JNDI查找方法,结果相同。
try {
Context context = new InitialContext();
LOG.info("context=%s", context);
connectionFactory = (ConnectionFactory) context.lookup("jms/artemis");
LOG.info("connectionFactory=%s", connectionFactory);
}catch(Exception e) {
e.printStackTrace();
return "no connectionFactory found on JNDI";
}
我希望将 jms/artem
your text
注射到我的 ConnectionFactory
上,但从未发生过。
调用
context.lookup()
时得到的实际异常是:
javax.naming.NoInitialContextException: \
Need to specify class name in environment or system property, \
or as an applet parameter, or in an application resource file: \
java.naming.factory.initial
这就是 JNDI 的工作原理,您需要特殊准备才能在 OSGi 中使用它(Fuse Karaf 是基于 Apache Karaf 的 OSGi 运行时)。
您必须先安装
jndi
功能。那么你的例外将是:
javax.naming.NotContextException: jms/artemis
然而,它几乎是您需要的一切。
jndi
功能为您提供了多个命令,例如:
karaf@root()> jndi:names
JNDI Name │ Class Name
─────────────────────────┼─────────────────────────────────────────────────────────────────
osgi:service/jms/artemis │ org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory
osgi:service/jndi │ org.apache.karaf.jndi.internal.JndiServiceImpl
如果您现在使用
osgi:service/jms/artemis
而不仅仅是 jms/artemis
,您将获得正确的连接工厂。我在日志中得到了这个:
2023-01-02 09:45:53,412 INFO {XNIO-2 task-1} [grgr.test.Activator7$1.doGet()] \
(Activator7.java:65) : connectionFactory=ActiveMQConnectionFactory [serverLocator=ServerLocatorImpl \
[initialConnectors=[TransportConfiguration(name=null, factory=org-apache-activemq-artemis-core-remoting-impl-netty-NettyConnectorFactory) \
?port=61616&host=localhost], discoveryGroupConfiguration=null], \
clientID=null, consumerWindowSize = 1048576, \
dupsOKBatchSize=1048576, transactionBatchSize=1048576, readOnly=falseEnableSharedClientID=false]
您可以在 Fuse Karaf 此处找到更多持久性使用示例。
开发者文档位于此处。