I am writing an application using Akka, Akka-Camel and Spring for configuration. The application should act as a stand-alone JMS client for various application servers, for which it needs to configure the JMS connection factory using JNDI. I am testing this with jBoss. I have the same problem with jBoss 5 and 6 (this seems to be a Spring client problem not related to jBoss).
I am configuring Spring beans with this xml:
<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>
As you can see, I am setting up:
- ConnectionFactory initialized via JNDI is called jmsConnectionFactory
- JmsComponent component with connectionFactory property set in previous bean
In this configuration, my application does not work at startup using this:
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]
This comes from this code in JmsConfiguration.java:
protected ConnectionFactory createConnectionFactory() { ObjectHelper.notNull(connectionFactory, "connectionFactory"); return null; }
So, it looks like the initialization of Spring beans cannot bind / connect beans, as indicated here (extracted from Spring's fully saved XML configuration):
<bean name="jms" class="org.apache.camel.component.jms.JmsComponent"> <property name="connectionFactory" ref="jmsConnectionFactory" /> </bean>
I also tried to create an intermediate JmsConfiguration bean and set the JmsComponent configuration property, instead of setting the connectionFactory property directly, but I get the same result in both settings.
By the way, I can connect beans by code. I mean this:
val connFactory = springContext.getBean[javax.jms.ConnectionFactory]("jmsConnectionFactory", classOf[javax.jms.ConnectionFactory]) camelContext.addComponent("jms", JmsComponent.jmsComponentAutoAcknowledge(connFactory))
works great. So I know that I get ConnectionFactory from JNDI, I just can't get into the correct Spring configuration to bind it in XML.
I need this application to be very customizable without recompiling, so getting XML to work is a must for me.
In case this is unclear, the question arises: how do I get Spring to configure my JmsComponent bean, with its connectionFactory set to a JNDI-received factory?
EDIT: Camel's point of use is that it should allow me to exchange this component even for another other type. So today I use JMS, maybe tomorrow I will use TCP. That's why it would be important to be able to define everything in XML.