Search code examples
springjboss7.xspring-annotationsspring-jmsjmstemplate

Cannot find the JBoss ConnectionFactory with a JNDI lookup in Spring annotation configuration


Despite what seems to be a successful binding of the JBoss (AS 7.1.1.Final) connection factory:

[org.jboss.as.messaging] (MSC service thread 1-9) JBAS011601: Bound messaging object to jndi name java:/ConnectionFactory

The ConnectionFactory in the lookup is always null. Can anyone see what the problem is?

@Configuration
@ComponentScan(basePackages = "reservation")
public class AppConfiguration extends WebMvcConfigurerAdapter {

    // ***********************//
    // ******** JMS **********//
    // ***********************//
    @Bean
    public ConnectionFactory jmsConnectionFactory() {
        JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
        jndiObjectFactoryBean.setJndiName("java:/ConnectionFactory");
        return (ConnectionFactory) jndiObjectFactoryBean.getObject();
    }

    @Bean
    public Queue requestsQueue() {
        JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
        jndiObjectFactoryBean.setJndiName("java:/queue/test");
        return (Queue) jndiObjectFactoryBean.getObject();
    }

    @Bean
    public JmsOperations jmsOperations() {
        final JmsTemplate jmsTemplate = new JmsTemplate(jmsConnectionFactory());
        jmsTemplate.setDefaultDestination(requestsQueue());
        return jmsTemplate;
    }
}

Solution

  • Unfortunately you must call afterPropertiesSet() manually:

    @Bean
    public ConnectionFactory jmsConnectionFactory() {
        JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
        jndiObjectFactoryBean.setJndiName("java:/ConnectionFactory");
        jndiObjectFactoryBean.afterPropertiesSet();                    //HERE
        return (ConnectionFactory) jndiObjectFactoryBean.getObject();
    }
    

    An alternative I particularly like is as follows:

    @Bean
    public JndiObjectFactoryBean jmsConnectionFactoryFactoryBean() {
        JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
        jndiObjectFactoryBean.setJndiName("java:/ConnectionFactory");
        return jndiObjectFactoryBean;
    }
    
    public ConnectionFactory jmsConnectionFactory() {
        return (ConnectionFactory) jmsConnectionFactoryFactoryBean().getObject();
    }
    

    Notice that jmsConnectionFactory() is not annotated with @Bean (it's important). In that case Spring will call appropriate callback method for you.