Search code examples
javaspringspring-bootamqpspring-rabbit

Not able to send a simple "Hello World" message to RabbitMQ queue using Spring Boot


I am not able to send a message to RabbitMQ server using Spring Boot. I do not see any exception. Not sure what's going on.

I have admin-level access to the management console of RabbitMQ and can see if the queue is getting created or not. But I do not see any queue getting created. Moreover in the console logs all I see is this.

Console Logs:

2017-08-15 11:32:17.015  INFO 8256 --- [           main] com.study.jms.BasicApplication           : Starting BasicApplication on KOP-DBT0J12 with PID 8256 (C:\NITAL\MY-DATA\CODE-SAMPLES\SPRINGBOOT-MESSAGING-SAMPLES\rabbitmq\rabbitmq-helloworld-producer-demo\target\classes started by chandeln in C:\NITAL\MY-DATA\CODE-SAMPLES\SPRINGBOOT-MESSAGING-SAMPLES\rabbitmq\rabbitmq-helloworld-producer-demo)
2017-08-15 11:32:17.020  INFO 8256 --- [           main] com.study.jms.BasicApplication           : No active profile set, falling back to default profiles: default
2017-08-15 11:32:17.112  INFO 8256 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@73d4cc9e: startup date [Tue Aug 15 11:32:17 EDT 2017]; root of context hierarchy
2017-08-15 11:32:17.915  INFO 8256 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.amqp.rabbit.annotation.RabbitBootstrapConfiguration' of type [org.springframework.amqp.rabbit.annotation.RabbitBootstrapConfiguration$$EnhancerBySpringCGLIB$$1c012f1] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-08-15 11:32:18.739  INFO 8256 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2017-08-15 11:32:18.749  INFO 8256 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Bean with name 'rabbitConnectionFactory' has been autodetected for JMX exposure
2017-08-15 11:32:18.749  INFO 8256 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Located managed bean 'rabbitConnectionFactory': registering with JMX server as MBean [org.springframework.amqp.rabbit.connection:name=rabbitConnectionFactory,type=CachingConnectionFactory]
2017-08-15 11:32:18.769  INFO 8256 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase -2147482648
2017-08-15 11:32:18.779  INFO 8256 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 2147483647
2017-08-15 11:32:18.839  INFO 8256 --- [           main] com.study.jms.BasicApplication           : Started BasicApplication in 2.208 seconds (JVM running for 2.668)
2017-08-15 11:32:18.883  INFO 8256 --- [           main] o.s.a.r.c.CachingConnectionFactory       : Created new connection: rabbitConnectionFactory#2cc44ad:0/SimpleConnection@61f05988 [delegate=amqp://[email protected]:5672/, localPort= 65025]

BasicApplication.java

@SpringBootApplication
public class BasicApplication {

    private static RabbitTemplate rabbitTemplate;

    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(BasicApplication.class, args);
        rabbitTemplate = ctx.getBean(RabbitTemplate.class);
        rabbitTemplate.convertAndSend("helloworld.q", "Hello World !");
    }

}

application.properties

spring.rabbitmq.host=gsi-547576
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=admin

pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.6.RELEASE</version>
    <relativePath/>
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-amqp</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

Solution

  • You are missing RabbitMQ Queue bean definition:

    @Bean
    public Queue queue() {
        return new Queue("helloworld.q", false);
    }
    

    RabbitMQ requires queues to be created before publishing any message to them. One way to do it in Spring Boot is to define Queue bean and Spring Boot will handle it's creation. When you add it you will see something like this in your console log:

    2017-08-15 18:32:16.929  INFO 21163 --- [           main] o.s.amqp.rabbit.core.RabbitAdmin         : Auto-declaring a non-durable, auto-delete, or exclusive Queue (helloworld.q) durable:false, auto-delete:false, exclusive:false. It will be redeclared if the broker stops and is restarted while the connection factory is alive, but all messages will be lost.
    

    Of course you can define multiple beans of type Queue - all of them will be created. How it's done? RabbitAdmin component loads all Declarable beans and creates e.g. queues from Spring beans with type Queue.

    I have just tested following simple Spring Boot app:

    import org.springframework.amqp.core.Queue;
    import org.springframework.amqp.rabbit.core.RabbitTemplate;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.Bean;
    
    @SpringBootApplication
    public class Application {
    
        @Bean
        Queue queue() {
            return new Queue("helloworld.q", false);
        }
    
        public static void main(String[] args) throws InterruptedException {
            ApplicationContext ctx = SpringApplication.run(Application.class, args);
    
            RabbitTemplate rabbitTemplate = ctx.getBean(RabbitTemplate.class);
            rabbitTemplate.convertAndSend("helloworld.q", "Hello World !");
        }
    }
    

    And after running here is what I see in RabbitMQ admin:

    enter image description here

    enter image description here

    Of course this queue was not created beforehand. I hope it helps.