I am trying to get a simple Spring Integration test working to retrieve messages from a JMS queue hosted by HornetQ on JBoss EAP (version 6.4.0.GA running on Windows 7 Pro) running in standalone mode (standalone.bat -c standalone-full.xml).
The JMS test ran fine when using a simple Java JMS program; now, I'm trying to add Spring Integration and I get the following error:
18:29:03,197 ERROR [org.springframework.jms.listener.DefaultMessageListenerContainer]
(org.springframework.jms.listener.DefaultMessageListenerContainer#0-1)
Could not refresh JMS Connection for destination 'anotherQueue' -
retrying in 5000 ms. Cause: AOP configuration seems to be invalid:
tried calling method [public abstract javax.jms.Connection javax.jms.ConnectionFactory.createConnection()
throws javax.jms.JMSException] on target [HornetQQueue[anotherQueue]];
nested exception is java.lang.IllegalArgumentException: java.lang.ClassCastException@511504f4
The Spring config files are:
applicationContext-ordering-inbound-jms-spring-integration.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop=...
<bean id="jndiTemplateBilling" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">org.jboss.as.naming.InitialContextFactory</prop>
<prop key="java.naming.provider.url">remote://localhost:4447</prop>
</props>
</property>
</bean>
<bean id="jndiObjectFactoryBeanBilling" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate" ref="jndiTemplateBilling" />
<property name="jndiName" value="java:jboss/exported/jms/queue/anotherQueue" />
<property name="lookupOnStartup" value="false" />
<property name="proxyInterfaces">
<list>
<value>javax.jms.QueueConnectionFactory</value>
<value>javax.jms.TopicConnectionFactory</value>
<value>java.io.Externalizable</value>
</list>
</property>
</bean>
<bean id="jndiDestinationResolver"
class="org.springframework.jms.support.destination.JndiDestinationResolver">
<property name="jndiTemplate" ref="jndiTemplateBilling" />
<property name="cache" value="true" />
</bean>
<int-jms:inbound-gateway
request-destination-name="anotherQueue"
request-channel="inboundOrderingBillingJms"
destination-resolver="jndiDestinationResolver"
connection-factory="jndiObjectFactoryBeanBilling" />
<int:channel id="inboundOrderingBillingJms" /> <!-- handled by OrderingBillingInboundEndpoint -->
<context:component-scan base-package="com.att.ordering.endpoints.jms" />
<context:annotation-config />
<context:spring-configured />
<int:annotation-config />
</beans>
and applicationContext-ordering-inbound-jms.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans ...">
<context:annotation-config />
<context:spring-configured />
<int:annotation-config />
<context:component-scan base-package="com.att.ordering.endpoints.jms"/>
</beans>
The ServiceActivator class:
package com.att.ordering.endpoints.jms;
import javax.xml.bind.JAXBElement;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class OrderingBillingInboundEndpoint
{
@ServiceActivator(inputChannel = "inboundOrderingBillingJms")
//public void handleMessage(JAXBElement<String> accountNumber)
public void handleMessage(String accountNumber)
{
System.out.println("In OrderingBillingInboundEndpoint.handleMessage - accountNumber=" + accountNumber);
}
}
I bootstrap spring with a WAR; WEB-INF/web.xml is:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>parentContextKey</param-name>
<param-value>ordering-spring-bootstrap.war.context</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</context-param>
</web-app>
WEB-INF/classes/beanRefContext.xml is:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="ordering-spring-bootstrap.war.context"
class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg>
<list>
<value>/applicationContext-ordering-inbound-jms-spring-integration.xml</value>
<value>/applicationContext-ordering-inbound-jms.xml</value>
</list>
</constructor-arg>
</bean>
</beans>
FOLLOWING ADDED AFTER ARTEM'S INITIAL REPLY
My JNDI name is java:jboss/exported/jms/queue/anotherQueue. It is bound to HornetQQueue[anotherQueue].
Following shows it in JBoss - note: there are 2 JNDI entries; I'm using the second one:
This is correct - I was able to get a Java JMS program (without Spring Integration) working as follows:
final Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
env.put(Context.PROVIDER_URL, "remote://localhost:4447");
env.put(Context.SECURITY_PRINCIPAL, "appuser");
env.put(Context.SECURITY_CREDENTIALS, "appuser1!");
context = new InitialContext(env);
// JNDI name in JBoss is: java:jboss/exported/jms/queue/anotherQueue
connectionFactory = (ConnectionFactory) context.lookup("jms/RemoteConnectionFactory");
destination = (Destination) context.lookup("jms/queue/anotherQueue");
connection = connectionFactory.createConnection("appuser", "appuser1!");
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
consumer = session.createConsumer(destination);
consumer.setMessageListener(new MyListener());
connection.start();
I am now trying to get the same simple example working using Spring Integration.
Questions:
(A) Where should I put the user id and password?
(B) Is the following correct? If not, what should it exactly be?
<bean id="jndiTemplateBilling" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">org.jboss.as.naming.InitialContextFactory</prop>
<prop key="java.naming.provider.url">remote://localhost:4447</prop>
</props>
</property>
</bean>
(C) How should I change the following? I removed the proxyInterfaces; what else should change? I don't know how to use jee:jndi-lookup
<bean id="jndiObjectFactoryBeanBilling" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate" ref="jndiTemplateBilling" />
<property name="jndiName" value="java:jboss/exported/jms/queue/anotherQueue" />
<property name="lookupOnStartup" value="false" />
</bean>
(D) Does the following stay the same?
<bean id="jndiDestinationResolver"
class="org.springframework.jms.support.destination.JndiDestinationResolver">
<property name="jndiTemplate" ref="jndiTemplateBilling" />
<property name="cache" value="true" />
</bean>
(E) Does the following change?
<int-jms:inbound-gateway
request-destination-name="anotherQueue"
request-channel="inboundOrderingBillingJms"
destination-resolver="jndiDestinationResolver"
connection-factory="jndiObjectFactoryBeanBilling" />