Vivek
Vivek

Reputation: 920

Active MQ, JNDI, Spring error

I am a starter in JNDI and JMS technology.

I have my JNDI file as:

java.naming.factory.initial = org.apache.activemq.jndi.ActiveMQInitialContextFactory

# use the following property to configure the default connector
java.naming.provider.url = nio://localhost:61616

# use the following property to specify the JNDI name the connection factory
# should appear as.
#jms.connectionFactoryNames = ConnectionFactory, queueConnectionFactory, topicConnectionFactry
connectionFactoryName = queueConnectionFactory
#connectionfactory.amqConnectionFactory = nio://localhost:61616

# register some queues in JNDI using the form
# queue.[jndiName] = [physicalName]
queue.requestQueue = dq-dataloader.requestqueue


# register some topics in JNDI using the form
# topic.[jndiName] = [physicalName]
#topic.MyTopic = example.MyTopic

My spring configuration file is:

 <?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:context="http://www.springframework.org/schema/context"
    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-3.0.xsd">

    <!-- <context:component-scan base-package="com.qpid.sample" /> -->

    <bean id="jndiProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="location" value="classpath:dq_dataloader-amq.properties" />
    </bean>

    <!-- JNDI template -->
    <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
        <property name="environment" ref="jndiProperties" />
    </bean>


    <!-- local ActiveMQ connection factory from JNDI context available via jndiTemplate -->
    <bean id="amqConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiTemplate" ref="jndiTemplate" />
        <property name="jndiName" value="connectionFactoryName" />
    </bean>

    <!-- caching connection factory -->
    <bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
        <property name="targetConnectionFactory" ref="amqConnectionFactory" />

        <!-- set the session cache size -->
        <property name="sessionCacheSize" value="10" />
    </bean>

    <bean id="taskRequestQueueBean" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiTemplate" ref="jndiTemplate" />
        <property name="jndiName" value="requestQueue" />
    </bean>

</beans>

Invoker class:

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jndi.JndiTemplate;

public class JMSSender {

    private static Log logger = LogFactory.getLog(JMSSender.class);
    JndiTemplate jndiTemplate;

    public void init() {
        ApplicationContext context = new ClassPathXmlApplicationContext("dq-dataloader-amq-beans.xml");
        jndiTemplate = (JndiTemplate) context.getBean("jndiTemplate");
        logger.info(""+jndiTemplate.getEnvironment().getProperty("java.naming.provider.url"));

    }

    public static void main(String [] argv) {
        JMSSender sender = new JMSSender();
        sender.init();
    }
}

But when I am trying to initialize them I am getting this error:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'amqConnectionFactory' defined in class path resource [dq-dataloader-amq-beans.xml]: Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: connectionFactoryName
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1486)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:524)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:608)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at com.jpmorgan.cri.dqaf.amq.jms.JMSSender.init(JMSSender.java:15)
    at com.jpmorgan.cri.dqaf.amq.jms.JMSSender.main(JMSSender.java:24)
Caused by: javax.naming.NameNotFoundException: connectionFactoryName
    at org.apache.activemq.jndi.ReadOnlyContext.lookup(ReadOnlyContext.java:235)
    at javax.naming.InitialContext.lookup(InitialContext.java:392)
    at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:154)
    at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:87)

Any help would be appreciated.

Regards.

Upvotes: 1

Views: 3688

Answers (3)

byron
byron

Reputation: 1

in dq_dataloader-amq.properties

you should define param

connectionFactoryName = queueConnectionFactory as

connectionFactoryNames = queueConnectionFactory

then update as

<bean id="amqConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
      <property name="jndiTemplate" ref="jndiTemplate" />
      <property name="jndiName" value="queueConnectionFactory" />
</bean>

code in ActiveMQInitialContextFactory

protected String[] getConnectionFactoryNames(Map environment) {   
   String factoryNames = (String) environment.get("connectionFactoryNames");   

   if (factoryNames != null) {   
      List<String> list = new ArrayList<String>();   

      for (StringTokenizer enumeration = new StringTokenizer(factoryNames, ","); enumeration.hasMoreTokens();) {   
          list.add(enumeration.nextToken().trim());   
      }   

      int size = list.size();   

      if (size > 0) {   
           String[] answer = new String[size];   
           list.toArray(answer);   
           return answer;   
      }   
   }   

   return DEFAULT_CONNECTION_FACTORY_NAMES;   
}

Upvotes: 0

Benjamin C
Benjamin C

Reputation: 149

It seems to me that you had a simple case issue about the connection factory name.

It should be an upper case Q like this:

connectionFactoryName = QueueConnectionFactory

instead of "queueConnectionFactory".

Upvotes: 1

Jean-Philippe Bond
Jean-Philippe Bond

Reputation: 10649

You are not able to find the amqConnectionFactory in the JNDI because you try to get the object with the wrong JNDI name. You probably want to get the connectionFactoryName property value from dq_dataloader-amq.properties instead of the key.

Use ${} to get the value from the properties file.

<bean id="amqConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiTemplate" ref="jndiTemplate" />
    <property name="jndiName" value="${connectionFactoryName}" />
</bean>

Upvotes: 1

Related Questions