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://admin@172.25.20.43: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>
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:
Of course this queue was not created beforehand. I hope it helps.