Redhat Fuse-Karaf无法注入JMS ConnectionFactory问题求助
解决Fuse Karaf中JMS ConnectionFactory注入失败问题
先确认连接工厂的实际注册状态
先在Karaf控制台执行osgi:service list | grep ConnectionFactory,看看jms/artemis对应的ConnectionFactory有没有真的注册到OSGi服务注册表,而且是不是标准的javax.jms.ConnectionFactory类型。
- 如果没找到,说明连接工厂配置有问题——虽然
jms:send能用,但可能是用了内部临时实例。得检查etc/org.apache.activemq.artemis.cfg或你用的配置文件,确保connectionFactory的id是jms/artemis,并且手动加上registerOSGiService=true(Artemis默认可能没开这个配置)。
排查@Reference注解的使用问题
如果用Declarative Services(DS)的@Reference,注意这几点:
- 你的Servlet类必须是OSGi组件,得加
@Component注解,还要指定服务类型(比如service = Servlet.class),不然DS不会处理你的@Reference。 @Reference里要加目标过滤器,匹配连接工厂的id:
或者用组件名称匹配:@Reference(target = "(osgi.jndi.service.name=jms/artemis)") private ConnectionFactory connectionFactory;@Reference(name = "connectionFactory", target = "(component.name=jms/artemis)")- 确保你的bundle依赖了
javax.jms和org.osgi.service.component.annotations包,在pom.xml里要加对应的Import-Package,或者直接用Karaf的feature引入jms和scr特性。
修复JNDI lookup的问题
用JNDI的话,不能直接用普通的InitialContext,得用OSGi的JNDI上下文:
- 正确的lookup代码应该是这样:
要是连接工厂注册时设置了Context context = new InitialContext(); ConnectionFactory cf = (ConnectionFactory) context.lookup("osgi:service/javax.jms.ConnectionFactory/(osgi.jndi.service.name=jms/artemis)");osgi.jndi.service.name=jms/artemis,也可以简化成:ConnectionFactory cf = (ConnectionFactory) context.lookup("jms/artemis"); - 还要确保你的bundle依赖了
org.osgi.service.jndi包,并且Karaf已经启动了org.apache.aries.jndibundle(用bundle:list | grep aries-jndi检查)。
检查Bundle的依赖和启动顺序
- 你的Servlet bundle必须在
jms/artemis连接工厂对应的bundle之后启动,不然启动时找不到服务。可以在pom.xml里加Require-Bundle或者Import-Package声明依赖,或者用Karaf的start-level调整启动顺序。 - 执行
bundle:headers 你的bundleID,看看Import-Package里的javax.jms状态是不是RESOLVED,要是UNRESOLVED,说明依赖没满足。
验证连接工厂的配置细节
- 检查Artemis的连接工厂配置,确保
connectionURL是正确的AMQP地址(比如ActiveMQ Classic 5.9默认AMQP端口是5672,地址就是tcp://localhost:5672),user和password也得配置正确。 - 用
jms:info connectionFactory jms/artemis命令查看连接工厂的详细信息,确认osgi.jndi.service.name确实设成了jms/artemis。
内容的提问来源于stack exchange,提问作者Camilo Vasquez
相关产品推荐
相关产品推荐

