Andriy Andrunevchyn
Andriy Andrunevchyn

Reputation: 498

Spring Jms @JmsListener annotation doesnt work

I have such method

    @JmsListener(containerFactory = "jmsListenerContainerFactory", destination = "myQName")
      public void rceive(MySerializableObject message) {
        log.info("received: {}", message);
      }

and such config on xml

<jms:annotation-driven />
    <bean id="jmsListenerContainerFactory" class="org.springframework.jms.config.DefaultJmsListenerContainerFactory">
        <property name="connectionFactory" ref="pooledConnectionFactory" />
        <property name="concurrency" value="3-10" />
    </bean>
<bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" value="${brokerURL}" />
    </bean>

    <bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
        <property name="maxConnections" value="5" />
        <property name="maximumActiveSessionPerConnection" value="500" />
        <property name="connectionFactory" ref="jmsConnectionFactory" />
    </bean>


    <bean id="jmsContainerFactory" class="org.springframework.jms.config.DefaultJmsListenerContainerFactory">
        <property name="connectionFactory" ref="pooledConnectionFactory" />
        <property name="concurrency" value="3-10" />
    </bean>
    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate" p:connectionFactory-ref="pooledConnectionFactory" />

Seems consumer was not created. I can send messages but cannot receive them. Any idea whats wrong here?

Upvotes: 2

Views: 7699

Answers (1)

Artem Bilan
Artem Bilan

Reputation: 121542

Just tested your config and it works well. Only difference that I make a class with @JmsListener as a <bean> in that context:

<bean class="org.springframework.integration.jms.JmsListenerAnnotationTests$TestService"/>

@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@DirtiesContext
public class JmsListenerAnnotationTests {

    @Autowired
    private JmsTemplate jmsTemplate;

    @Autowired
    private TestService testService;

    @Test
    public void test() throws InterruptedException {
        this.jmsTemplate.convertAndSend("myQName", "foo");
        assertTrue(this.testService.receiveLatch.await(10, TimeUnit.SECONDS));
        assertNotNull(this.testService.received);
        assertEquals("foo", this.testService.received);
    }

    public static class TestService {

        private CountDownLatch receiveLatch = new CountDownLatch(1);

        private Object received;

        @JmsListener(containerFactory = "jmsListenerContainerFactory", destination = "myQName")
        public void receive(String message) {
            this.received = message;
            this.receiveLatch.countDown();
        }

    }

}

<jms:annotation-driven /> makes the @JmsListener infrastructure available, but to force Spring to see those methods your classes should be beans anyway.

For example <component-scan> for the package with @Service classes.

Cheers!

Upvotes: 4

Related Questions