我正在编写一个使用 Akka、Akka-Camel 和 Spring 进行配置的应用程序。应用程序需要针对各种应用程序服务器充当独立的 JMS 客户端,为此它需要使用 JNDI 设置 JMS 连接工厂。我正在用 jBoss 对此进行测试。我对 jBoss 5 和 6 有同样的问题(这似乎是客户端 Spring 问题,与 jBoss 无关)。
我正在用这个 xml 配置 Spring bean:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:camel="http://camel.apache.org/schema/spring"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
">
<camelContext id="camel" trace="false" xmlns="http://camel.apache.org/schema/spring">
<jmxAgent id="agent" disabled="true"/>
</camelContext>
<jee:jndi-lookup id="jmsConnectionFactory" jndi-name="ConnectionFactory">
<jee:environment>
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=jnp://192.168.0.109:1099
</jee:environment>
</jee:jndi-lookup>
<bean name="jms" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory" ref="jmsConnectionFactory" />
</bean>
</beans>
如您所见,我正在设置:
- 通过 JNDI 初始化的 ConnectionFactory,称为 jmsConnectionFactory
- 一个 JmsComponent,其 connectionFactory 属性设置为前一个 bean
使用此配置,我的应用程序在启动时失败:
java.lang.IllegalArgumentException: connectionFactory must be specified
at org.apache.camel.util.ObjectHelper.notNull(ObjectHelper.java:294) ~[camel-core.jar:2.10.4]
at org.apache.camel.component.jms.JmsConfiguration.createConnectionFactory(JmsConfiguration.java:1053) ~[camel-jms.jar:2.10.4]
at org.apache.camel.component.jms.JmsConfiguration.getConnectionFactory(JmsConfiguration.java:416) ~[camel-jms.jar:2.10.4]
at org.apache.camel.component.jms.JmsConfiguration.createListenerConnectionFactory(JmsConfiguration.java:1062) ~[camel-jms.jar:2.10.4]
at org.apache.camel.component.jms.JmsConfiguration.getListenerConnectionFactory(JmsConfiguration.java:435) ~[camel-jms.jar:2.10.4]
at org.apache.camel.component.jms.JmsConfiguration.configureMessageListenerContainer(JmsConfiguration.java:889) ~[camel-jms.jar:2.10.4]
at org.apache.camel.component.jms.JmsConfiguration.createMessageListenerContainer(JmsConfiguration.java:379) ~[camel-jms.jar:2.10.4]
这来自 JmsConfiguration.java 中的这段代码:
protected ConnectionFactory createConnectionFactory() {
ObjectHelper.notNull(connectionFactory, "connectionFactory");
return null;
}
因此,看起来 Spring bean 初始化未能按照此处的说明关联/连接 bean(从先前粘贴的完整 XML Spring 配置中提取):
<bean name="jms" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory" ref="jmsConnectionFactory" />
</bean>
我还尝试创建一个中间 JmsConfiguration bean,并设置 JmsComponent 的配置属性,而不是直接设置 connectionFactory 属性,但是在两种设置中我得到了相同的结果。
顺便说一句,我可以通过代码连接 bean 好吧。我的意思是:
val connFactory = springContext.getBean[javax.jms.ConnectionFactory]("jmsConnectionFactory", classOf[javax.jms.ConnectionFactory])
camelContext.addComponent("jms", JmsComponent.jmsComponentAutoAcknowledge(connFactory))
工作得很好。所以我知道我从 JNDI 获得 ConnectionFactory,只是我无法使用正确的 Spring 配置来将其连接到 XML 中。
我需要这个应用程序在不重新编译的情况下是非常可配置的,所以让 XML 工作对我来说是必须的。
如果不清楚,问题是:如何让 Spring 设置我的 JmsComponent bean,并将其 connectionFactory 设置为 JNDI 获得的工厂?
编辑:使用 Camel 的目的是它应该允许我将这个组件交换为另一个不同类型的组件。所以今天我使用 JMS,也许明天我将使用 TCP。这就是为什么能够在 XML 中定义所有内容很重要的原因。