-
Spring JMS with ActiveMQ
Hello,
I am sorry if i have started a thread the format of which could probably exist. Moderators please move this thread to the appropriate area if required.
I am trying to get acquainted to spring jms functionalities as i need to use it as a part of several projects we have in the pipeline and i am kinda running short of time here as usual with developers.
I scooped up a couple of code snippets from the net and i have tweaked the spring config file as i am using ActiveMQ as my local MQ manager.
Here is my spring config file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//Spring//DTD Bean//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<!-- Application Context -->
<beans>
<!-- JNDI Environment Template -->
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">org.apache.activ emq.jndi.ActiveMQInitialContextFactory</prop>
<prop key="java.naming.provider.url">tcp://localhost:61616</prop>
</props>
</property>
</bean>
<!-- JMS Queue Connection Factory -->
<bean id="internalJmsQueueConnectionFactory"
class="org.springframework.jndi.JndiObjectFactoryB ean">
<property name="jndiTemplate">
<ref bean="jndiTemplate"/>
</property>
<property name="jndiName">
<value>MyQueue</value>
</property>
</bean>
<!-- Spring Wrapped JMS Queue Connection Factory -->
<bean id="jmsQueueConnectionFactory"
class="org.springframework.jms.connection.SingleCo nnectionFactory102">
<property name="targetConnectionFactory">
<ref bean="internalJmsQueueConnectionFactory"/>
</property>
<property name="pubSubDomain">
<value>false</value>
</property>
</bean>
<!-- JMS Destination Resolver -->
<bean id="jmsDestinationResolver"
class="org.springframework.jms.support.destination .JndiDestinationResolver">
<property name="jndiTemplate">
<ref bean="jndiTemplate"/>
</property>
<property name="cache">
<value>true</value>
</property>
</bean>
<!-- JMS Queue Template -->
<bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate102 ">
<property name="connectionFactory">
<!-- <ref bean="jmsQueueConnectionFactory"/>-->
<ref bean="internalJmsQueueConnectionFactory"/>
</property>
<property name="destinationResolver">
<ref bean="jmsDestinationResolver"/>
</property>
<property name="pubSubDomain">
<value>false</value>
</property>
<property name="receiveTimeout">
<value>20000</value>
</property>
</bean>
<bean id="jmsSender" class="springexample.client.JMSSender">
<property name="jmsTemplate102">
<ref bean="jmsQueueTemplate"/>
</property>
</bean>
<bean id="jmsReceiver" class="springexample.client.JMSReceiver">
<property name="jmsTemplate102">
<ref bean="jmsQueueTemplate"/>
</property>
</bean>
</beans>
and when i run my associated programs, i get a type mismatch for "connectionFactory" under "jmsQueueTemplate". The exact exception that i see is org.springframework.beans.TypeMismatchException: Failed to convert property value of type [org.apache.activemq.command.ActiveMQQueue] to required type [javax.jms.ConnectionFactory] for property 'targetConnectionFactory'; nested exception is java.lang.IllegalArgumentException:
How should i go about casting the objects to the appropriate type?
Let me know if you guys need any more information regarding the code and/or error.
Any help is truly appreciated
Thanks Whiz
-
Seems like it somehow injects a Queue instead of the connection factory.
Here' some sample code from the ActiveMQ site (http://activemq.apache.org/spring-support.html):
<!-- a pooling based JMS provider -->
<bean id="jmsFactory" class="org.apache.activemq.pool.PooledConnectionFa ctory" destroy-method="stop">
<property name="connectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFacto ry">
<property name="brokerURL">
<value>tcp://localhost:61616</value>
</property>
</bean>
</property>
</bean>
<!-- Spring JMS Template -->
<bean id="myJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory">
<ref local="jmsFactory"/>
</property>
</bean>
/S
-
Quote:
Code:
<!-- JMS Queue Connection Factory -->
<bean id="internalJmsQueueConnectionFactory"
class="org.springframework.jndi.JndiObjectFactoryB ean">
<property name="jndiTemplate">
<ref bean="jndiTemplate"/>
</property>
<property name="jndiName">
<value>MyQueue</value>
</property>
</bean>
Your problem seems that you take a queue instead of a connection factory from the jndi registry. That gives you a type mismatch. Casting wouldn't help you.
(btw, you should really switch to schema instead of dtd ;))
-
Here is what i have done so far...
1. I switched to schema from dtd - adhering to the latest specs :) , thanks iwein
2. PooledConnectionFactory does not get wired into the JNDI
So my problem is now, how do i convert the PooledConnectionFactory so that i can utilize it as a lookup object through JNDI OR how can i get a ConnectionFactory using ActiveMQConnectionFactory OR is there any other alternative?
This is how my latest spring config looks like
<?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:amq="http://activemq.org/config/1.0"
xmlns:jms="http://www.springframework.org/schema/jms"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schem...-beans-2.0.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schem...ng-jms-2.5.xsd
http://activemq.org/config/1.0 http://activemq.apache.org/schema/core/activemq-core-5.0.0.xsd">
<!-- Application Context -->
<bean id="jmsFactory" class="org.apache.activemq.pool.PooledConnectionFa ctory" destroy-method="stop">
<property name="connectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFacto ry">
<property name="brokerURL">
<value>tcp://localhost:61616</value>
</property>
</bean>
</property>
</bean>
<!-- JNDI Environment Template -->
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">
<!-- org.apache.activemq.pool.PooledConnectionFactory</prop> -->
org.apache.activemq.jndi.ActiveMQInitialContextFac tory</prop>
<prop key="java.naming.provider.url">tcp://localhost:61616</prop>
</props>
</property>
</bean>
<!-- JMS Queue Connection Factory -->
<bean id="internalJmsQueueConnectionFactory"
class="org.springframework.jndi.JndiObjectFactoryB ean">
<property name="jndiTemplate">
<ref bean="jndiTemplate"/>
</property>
<property name="jndiName">
<value>MyQueue</value>
</property>
</bean>
<!-- Spring Wrapped JMS Queue Connection Factory -->
<bean id="jmsQueueConnectionFactory"
class="org.springframework.jms.connection.SingleCo nnectionFactory">
<property name="targetConnectionFactory">
<ref bean="internalJmsQueueConnectionFactory"/>
</property>
<!--<property name="pubSubDomain">
<value>false</value>
</property> -->
</bean>
<!-- JMS Destination Resolver -->
<bean id="jmsDestinationResolver"
class="org.springframework.jms.support.destination .JndiDestinationResolver">
<property name="jndiTemplate">
<ref bean="jndiTemplate"/>
</property>
<property name="cache">
<value>true</value>
</property>
</bean>
<!-- JMS Queue Template -->
<bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory">
<ref bean="jmsQueueConnectionFactory"/>
<!-- <ref bean="internalJmsQueueConnectionFactory"/> -->
</property>
<property name="destinationResolver">
<ref bean="jmsDestinationResolver"/>
</property>
<property name="pubSubDomain">
<value>false</value>
</property>
<property name="receiveTimeout">
<value>20000</value>
</property>
</bean>
<bean id="jmsSender" class="springexample.client.JMSSender">
<property name="jmsTemplate102">
<ref bean="jmsQueueTemplate"/>
</property>
</bean>
<bean id="jmsReceiver" class="springexample.client.JMSReceiver">
<property name="jmsTemplate102">
<ref bean="jmsQueueTemplate"/>
</property>
</bean>
</beans>