Spring Boot AMQP Receiver - spring

I'm creating a simple Spring Boot app that I want to receive messages sent to an AMQP (Rabbit) exchange (from another application).
I am getting an error stating that the queue i'm to receive on does not exists. When I look at http://localhost:15672/#/queues i can see that it does; i delete it before starting this application.
I read on another post that if a queue does not exists, RabbitAdmin has to be declared and declareExchange() and declareQueue() used to overcome this.
Even with this in place I'm still seeing the same error. Furthermore, the error is confusing b/c it states:
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method(reply-code=404, reply-text=NOT_FOUND - no queue 'from-logger-exchange' in vhost '/', class-id=50, method-id=10)
Note the 'no queue' indicates my exchange name.
Here's the configuration code (i realize that Boot creates the connectionFactory & RabbitAdmin but started adding these when that wasn't working):
'import javax.annotation.PostConstruct;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration
public class Config {
#Value("${spring.activemq.broker-url}")
String host;
#Value("${spring.activemq.user}")
String userName;
#Value("${spring.activemq.password}")
String password;
#Value("${config.exchangeName}")
String exchangeName;
#Value("${config.queueName}")
String queueName;
#PostConstruct
public void printVariables() {
System.out.println("host " + host);
System.out.println("userName " + userName);
System.out.println("password " + password);
System.out.println("exchangeName " + exchangeName);
System.out.println("queueName " + queueName);
System.out.println("queue.name " + queue().getName());
System.out.println("exchange.name " + topicExchange().getName());
System.out.println("binding " + binding().toString());
System.out.println("connectionFactory " + connectionFactory().toString());
System.out.println("rabbitAdmin " + rabbitAdmin().toString());
}
#Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory(host);
connectionFactory.setUsername(userName);
connectionFactory.setPassword(password);
return connectionFactory;
}
#Bean
public RabbitAdmin rabbitAdmin() {
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory());
rabbitAdmin.declareExchange(topicExchange());
rabbitAdmin.declareQueue(queue());
return rabbitAdmin;
}
#Bean
public Queue queue() {
return new Queue(queueName);
}
// #Bean
// public FanoutExchange fanoutExchange() {
// return new FanoutExchange(exchangeName);
// }
public TopicExchange topicExchange() {
return new TopicExchange(exchangeName, false, true);
}
#Bean
public Binding binding() {
//return BindingBuilder.bind(queue()).to(fanoutExchange());
return BindingBuilder.bind(queue()).to(topicExchange()).with("my.routing.key");
}
#Bean
public Receiver receiver() {
return new Receiver();
}
}
'
Here's the Receiver:
import org.springframework.amqp.rabbit.annotation.RabbitListener;
public class Receiver {
#RabbitListener(queues="${config.exchangeName}")
public void receive(String input) {
System.out.println(" Receiver#receive input: " + input);
}
}
Here's the first bit of the console output:
. ____ _ __
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.3.2.RELEASE)
2016-02-23 10:20:47.710 INFO 18804 --- [ main] c.i.logging.receiver.Application : Starting Application on INT002520 with PID 18804 (C:\Users\matt.aspen\Documents\_logging\log-message-receiver2\target\classes started by matt.aspen in C:\Users\matt.aspen\Documents\_logging\log-message-receiver2)
2016-02-23 10:20:47.710 INFO 18804 --- [ main] c.i.logging.receiver.Application : No active profile set, falling back to default profiles: default
2016-02-23 10:20:47.710 DEBUG 18804 --- [ main] o.s.boot.SpringApplication : Loading source class com.intelligrated.logging.receiver.Application
2016-02-23 10:20:47.750 DEBUG 18804 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Loaded config file 'classpath:/application.properties'
2016-02-23 10:20:47.750 DEBUG 18804 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Skipped (empty) config file 'classpath:/application.properties' for profile default
2016-02-23 10:20:47.750 INFO 18804 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext#679b62af: startup date [Tue Feb 23 10:20:47 PST 2016]; root of context hierarchy
2016-02-23 10:20:48.482 INFO 18804 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.amqp.rabbit.annotation.RabbitBootstrapConfiguration' of type [class org.springframework.amqp.rabbit.annotation.RabbitBootstrapConfiguration$$EnhancerBySpringCGLIB$$68858653] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
host localhost
userName guest
password guest
exchangeName from-logger-exchange
queueName from-logger-queue
queue.name from-logger-queue
exchange.name from-logger-exchange
binding Binding [destination=from-logger-queue, exchange=from-logger-exchange, routingKey=my.routing.key]
connectionFactory CachingConnectionFactory [channelCacheSize=1, host=localhost, port=5672, active=true connectionFactory]
2016-02-23 10:20:48.642 INFO 18804 --- [ main] o.s.a.r.c.CachingConnectionFactory : Created new connection: SimpleConnection#6239aba6 [delegate=amqp://guest#127.0.0.1:5672/]
rabbitAdmin org.springframework.amqp.rabbit.core.RabbitAdmin#5f354bcf
2016-02-23 10:20:48.753 DEBUG 18804 --- [ main] inMXBeanRegistrar$SpringApplicationAdmin : Application Admin MBean registered with name 'org.springframework.boot:type=Admin,name=SpringApplication'
2016-02-23 10:20:48.998 INFO 18804 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2016-02-23 10:20:49.208 INFO 18804 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase -2147482648
2016-02-23 10:20:49.208 INFO 18804 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 2147483647
2016-02-23 10:20:49.218 WARN 18804 --- [cTaskExecutor-1] o.s.a.r.listener.BlockingQueueConsumer : Failed to declare queue:from-logger-exchange
2016-02-23 10:20:49.228 WARN 18804 --- [cTaskExecutor-1] o.s.a.r.listener.BlockingQueueConsumer : Queue declaration failed; retries left=3
org.springframework.amqp.rabbit.listener.BlockingQueueConsumer$DeclarationException: Failed to declare queue(s):[from-logger-exchange]
at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.attemptPassiveDeclarations(BlockingQueueConsumer.java:571) ~[spring-rabbit-1.5.3.RELEASE.jar:na]
at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:470) ~[spring-rabbit-1.5.3.RELEASE.jar:na]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1171) [spring-rabbit-1.5.3.RELEASE.jar:na]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_40]
Caused by: java.io.IOException: null
at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:106) ~[amqp-client-3.5.7.jar:na]
at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:102) ~[amqp-client-3.5.7.jar:na]
at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:124) ~[amqp-client-3.5.7.jar:na]
at com.rabbitmq.client.impl.ChannelN.queueDeclarePassive(ChannelN.java:885) ~[amqp-client-3.5.7.jar:na]
at com.rabbitmq.client.impl.ChannelN.queueDeclarePassive(ChannelN.java:61) ~[amqp-client-3.5.7.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_40]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_40]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_40]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_40]
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory$CachedChannelInvocationHandler.invoke(CachingConnectionFactory.java:764) ~[spring-rabbit-1.5.3.RELEASE.jar:na]
at com.sun.proxy.$Proxy31.queueDeclarePassive(Unknown Source) ~[na:na]
at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.attemptPassiveDeclarations(BlockingQueueConsumer.java:550) ~[spring-rabbit-1.5.3.RELEASE.jar:na]
... 3 common frames omitted
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no queue 'from-logger-exchange' in vhost '/', class-id=50, method-id=10)
at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:67) ~[amqp-client-3.5.7.jar:na]
at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:33) ~[amqp-client-3.5.7.jar:na]
at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:361) ~[amqp-client-3.5.7.jar:na]
at com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:226) ~[amqp-client-3.5.7.jar:na]
at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:118) ~[amqp-client-3.5.7.jar:na]
... 12 common frames omitted
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no queue 'from-logger-exchange' in vhost '/', class-id=50, method-id=10)
at com.rabbitmq.client.impl.ChannelN.asyncShutdown(ChannelN.java:484) ~[amqp-client-3.5.7.jar:na]
at com.rabbitmq.client.impl.ChannelN.processAsync(ChannelN.java:321) ~[amqp-client-3.5.7.jar:na]
at com.rabbitmq.client.impl.AMQChannel.handleCompleteInboundCommand(AMQChannel.java:144) ~[amqp-client-3.5.7.jar:na]
at com.rabbitmq.client.impl.AMQChannel.handleFrame(AMQChannel.java:91) ~[amqp-client-3.5.7.jar:na]
at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:554) ~[amqp-client-3.5.7.jar:na]
... 1 common frames omitted
2016-02-23 10:20:54.226 WARN 18804 --- [cTaskExecutor-1] o.s.a.r.listener.BlockingQueueConsumer : Failed to declare queue:from-logger-exchange
2016-02-23 10:20:54.226 WARN 18804 --- [cTaskExecutor-1] o.s.a.r.listener.BlockingQueueConsumer : Queue declaration failed; retries left=2
What's even more confusing is that when i look at http://localhost:15672/#/connections i see the connection, http://localhost:15672/#/channels i see the channel, http://localhost:15672/#/exchanges i see "from-logger-exchange", and http://localhost:15672/#/queues i see "from-logger-queue"

One problem is your exchange is not a #Bean.
I get
reply-code=404, reply-text=NOT_FOUND - no exchange 'from.logging.exchange' in vhost '/', class-id=50, method-id=20)
with your config. Adding #Bean to the exchange fixes it.
EDIT
Also (as Artem points out below), you have the wrong property on the listener
#RabbitListener(queues="${config.exchangeName}")
should be
#RabbitListener(queues="${config.queueName}")

Related

Spring can't resolve property placeholder but still supplies the value?

Currently working on a Spring application; I'm very new to Spring.
For some reason, Spring picks up my .properties file and injects the literal into my object. In the output, I see the appropriate line: com.test.Baseball#345e5a17 with the name "Chuck Norris". However, later in the stacktrace, it says that this value cannot be resolved:
com.test.Baseball#345e5a17 with the name "Chuck Norris"
14:58:39.618 [main] DEBUG org.springframework.context.support.ClassPathXmlApplicationContext -
Closing org.springframework.context.support.ClassPathXmlApplicationContext#e2d56bf, started on Mon
Dec 16 14:58:36 CST 2019
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.2.RELEASE)
2019-12-16 14:58:39.976 INFO 98376 --- [ main] .c.t.SpringAnnotationsProjectApplication :
Starting SpringAnnotationsProjectApplication on C001823506 with PID 98376 (C:\Users\\eclipse-
workspace\Spring-Annotations-project\target\classes started by in C:\Users\\eclipse-
workspace\Spring-Annotations-project)
2019-12-16 14:58:39.981 INFO 98376 --- [ main] .c.t.SpringAnnotationsProjectApplication :
No active profile set, falling back to default profiles: default
2019-12-16 14:58:40.878 INFO 98376 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer :
Tomcat initialized with port(s): 8080 (http)
2019-12-16 14:58:40.897 INFO 98376 --- [ main] o.apache.catalina.core.StandardService :
Starting service [Tomcat]
2019-12-16 14:58:40.898 INFO 98376 --- [ main] org.apache.catalina.core.StandardEngine :
Starting Servlet engine: [Apache Tomcat/9.0.29]
2019-12-16 14:58:41.126 INFO 98376 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] :
Initializing Spring embedded WebApplicationContext
2019-12-16 14:58:41.134 INFO 98376 --- [ main] o.s.web.context.ContextLoader :
Root WebApplicationContext: initialization completed in 1136 ms
2019-12-16 14:58:41.217 WARN 98376 --- [ main] ConfigServletWebServerApplicationContext :
Exception encountered during context initialization - cancelling refresh attempt:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'coach':
Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException:
Could not resolve placeholder 'coach.name' in value "${coach.name}"
2019-12-16 14:58:41.225 INFO 98376 --- [ main] o.apache.catalina.core.StandardService :
Stopping service [Tomcat]
2019-12-16 14:58:41.237 INFO 98376 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with
'debug' enabled.
2019-12-16 14:58:41.247 ERROR 98376 --- [ main] o.s.boot.SpringApplication :
Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'coach':
Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException:
Could not resolve placeholder 'coach.name' in value "${coach.name}"
at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:405) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1422) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:879) ~[spring-beans-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) ~[spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at com.cat.test.SpringAnnotationsProjectApplication.main(SpringAnnotationsProjectApplication.java:20) [classes/:na]
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'coach.name' in value "${coach.name}"
The .properties file:
coach.name="Chuck Norris"
coach.item="basketball"
The applicationContext.xml file:
<?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.xsd">
<context:component-scan base-package="com.test"></context:component-scan>
<context:property-placeholder location="classpath:PropertyValues.properties"/>
</beans>
The Coach class (the problem class):
package com.test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
#Component
public class Coach {
private SportsItem item;
#Value("${coach.name}")
private String name;
#Autowired
public Coach(#Qualifier("baseball") SportsItem item) {
this.item = item;
}
public void setItem(SportsItem item) {
this.item = item;
}
public SportsItem getItem() {
return item;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
my main class:
#SpringBootApplication
public class SpringAnnotationsProjectApplication {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Coach coachBean = context.getBean("coach", Coach.class);
System.out.println(coachBean.getItem() + " with the name " + coachBean.getName());
context.close();
SpringApplication.run(SpringAnnotationsProjectApplication.class, args);
}
}
What makes this strange is that in the very first line, we get the proper output. Despite this, Spring still detects a problem and shuts down.
What is going on here?
The reason you are seeing these errors is because you need to import the applicationContext.xml. You can do this by creating a configuration class that imports the resource. This is explained in this document: https://www.springboottutorial.com/spring-boot-java-xml-context-configuration. I have also included an example of what it would look like below.
#Configuration
#ImportResource({"classpath*:applicationContext.xml"})
public class XmlConfiguration
{
}

validate field length while reading csv file in spring batch

Is there any way to validate field length while reading csv file in spring-boot batch FlatFileItemReader?
I tried javax.validation and set min and max length in pojo, but don't know how to trigger the validation.
I have created an example here with READ.me here.
I override the FlatItemReader and then perform Bean Validation using Hibernate Validator at Reader level as below
public class SimpleReader extends FlatFileItemReader<SoccerTeam> {
private Validator factory = Validation.buildDefaultValidatorFactory().getValidator();
#Override
public SoccerTeam doRead() throws Exception {
SoccerTeam soccerTeam = super.doRead();
if (Objects.isNull(soccerTeam)) return null;
Set<ConstraintViolation<SoccerTeam>> violations = this.factory.validate(soccerTeam);
if (!violations.isEmpty()) {
System.out.println(violations);
String errorMsg = String.format("The input has validation failed. Data is '%s'", soccerTeam);
throw new FlatFileParseException(errorMsg, Objects.toString(soccerTeam));
}
else {
return soccerTeam;
}
}
}
The model is using validation annotation
package com.bigzidane.example.springbatch;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.Size;
public class SoccerTeam {
#Size(max = 60)
private String name;
private String national;
#Min(value = 1)
#Max(value = 100)
private int rank;
public void setName(String name) {
this.name = name;
}
public void setNational(String national) {
this.national = national;
}
public void setRank(int rank) {
this.rank = rank;
}
#Override
public String toString() {
return "SoccerTeam{" +
"name='" + name + '\'' +
", national='" + national + '\'' +
", rank='" + rank + '\'' +
'}';
}
}
For the full code, please take a look here
Example run locally
Input is
name,national,rank
real madrid,spain,100
ars,english,1
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.9.RELEASE)
2019-10-05 14:41:27.754 INFO 10912 --- [ main] c.b.example.springbatch.HelloBatch : Starting HelloBatch on WINDOWS-ESDA5FC with PID 10912 (C:\Users\dotha\IdeaProjects\spring-boot-batch\target\classes started by dotha in C:\Users\dotha\IdeaProjects\spring-boot-batch)
2019-10-05 14:41:27.760 INFO 10912 --- [ main] c.b.example.springbatch.HelloBatch : No active profile set, falling back to default profiles: default
2019-10-05 14:41:28.985 INFO 10912 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2019-10-05 14:41:29.232 INFO 10912 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2019-10-05 14:41:29.383 INFO 10912 --- [ main] o.s.b.c.r.s.JobRepositoryFactoryBean : No database type set, using meta data indicating: H2
2019-10-05 14:41:29.684 INFO 10912 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : No TaskExecutor has been set, defaulting to synchronous executor.
2019-10-05 14:41:29.934 INFO 10912 --- [ main] c.b.example.springbatch.HelloBatch : Started HelloBatch in 2.643 seconds (JVM running for 3.269)
2019-10-05 14:41:29.936 INFO 10912 --- [ main] o.s.b.a.b.JobLauncherCommandLineRunner : Running default command line with: []
2019-10-05 14:41:30.035 INFO 10912 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : Job: [FlowJob: [name=processJob]] launched with the following parameters: [{run.id=1}]
2019-10-05 14:41:30.066 INFO 10912 --- [ main] o.s.batch.core.job.SimpleStepHandler : Executing step: [step1]
SoccerTeam{name='real madrid', national='spain', rank='100'}
SoccerTeam{name='ars', national='english', rank='1'}
2019-10-05 14:41:30.220 INFO 10912 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : Job: [FlowJob: [name=processJob]] completed with the following parameters: [{run.id=1}] and the following status: [COMPLETED]
2019-10-05 14:41:30.225 INFO 10912 --- [ Thread-2] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2019-10-05 14:41:30.227 INFO 10912 --- [ Thread-2] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
Now if the input has validation failed
Input is
name,national,rank
real madrid,spain,101
ars,english,1
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.9.RELEASE)
2019-10-05 14:42:37.757 INFO 11268 --- [ main] c.b.example.springbatch.HelloBatch : Starting HelloBatch on WINDOWS-ESDA5FC with PID 11268 (C:\Users\dotha\IdeaProjects\spring-boot-batch\target\classes started by dotha in C:\Users\dotha\IdeaProjects\spring-boot-batch)
2019-10-05 14:42:37.761 INFO 11268 --- [ main] c.b.example.springbatch.HelloBatch : No active profile set, falling back to default profiles: default
2019-10-05 14:42:39.319 INFO 11268 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2019-10-05 14:42:39.648 INFO 11268 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2019-10-05 14:42:39.798 INFO 11268 --- [ main] o.s.b.c.r.s.JobRepositoryFactoryBean : No database type set, using meta data indicating: H2
2019-10-05 14:42:40.101 INFO 11268 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : No TaskExecutor has been set, defaulting to synchronous executor.
2019-10-05 14:42:40.372 INFO 11268 --- [ main] c.b.example.springbatch.HelloBatch : Started HelloBatch in 3.231 seconds (JVM running for 3.89)
2019-10-05 14:42:40.374 INFO 11268 --- [ main] o.s.b.a.b.JobLauncherCommandLineRunner : Running default command line with: []
2019-10-05 14:42:40.524 INFO 11268 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : Job: [FlowJob: [name=processJob]] launched with the following parameters: [{run.id=1}]
2019-10-05 14:42:40.559 INFO 11268 --- [ main] o.s.batch.core.job.SimpleStepHandler : Executing step: [step1]
[ConstraintViolationImpl{interpolatedMessage='must be less than or equal to 100', propertyPath=rank, rootBeanClass=class com.bigzidane.example.springbatch.SoccerTeam, messageTemplate='{javax.validation.constraints.Max.message}'}]
2019-10-05 14:42:40.746 ERROR 11268 --- [ main] o.s.batch.core.step.AbstractStep : Encountered an error executing step step1 in job processJob
org.springframework.batch.item.file.FlatFileParseException: The input has validation failed. Data is 'SoccerTeam{name='real madrid', national='spain', rank='101'}'
at com.bigzidane.example.springbatch.SimpleReader.doRead(SimpleReader.java:25) ~[classes/:na]
at com.bigzidane.example.springbatch.SimpleReader.doRead(SimpleReader.java:12) ~[classes/:na]
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.read(AbstractItemCountingItemStreamItemReader.java:92) ~[spring-batch-infrastructure-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.batch.core.step.item.SimpleChunkProvider.doRead(SimpleChunkProvider.java:94) ~[spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.batch.core.step.item.SimpleChunkProvider.read(SimpleChunkProvider.java:161) ~[spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.batch.core.step.item.SimpleChunkProvider$1.doInIteration(SimpleChunkProvider.java:119) ~[spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:375) ~[spring-batch-infrastructure-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) ~[spring-batch-infrastructure-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:145) ~[spring-batch-infrastructure-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.batch.core.step.item.SimpleChunkProvider.provide(SimpleChunkProvider.java:113) ~[spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:69) ~[spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:407) ~[spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:331) ~[spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.1.10.RELEASE.jar:5.1.10.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:273) ~[spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:82) ~[spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:375) ~[spring-batch-infrastructure-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) ~[spring-batch-infrastructure-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:145) ~[spring-batch-infrastructure-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:258) ~[spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:203) ~[spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148) [spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:68) [spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:67) [spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169) [spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144) [spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:136) [spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:313) [spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:144) [spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) [spring-core-5.1.10.RELEASE.jar:5.1.10.RELEASE]
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:137) [spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_161]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_161]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_161]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_161]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343) [spring-aop-5.1.10.RELEASE.jar:5.1.10.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) [spring-aop-5.1.10.RELEASE.jar:5.1.10.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) [spring-aop-5.1.10.RELEASE.jar:5.1.10.RELEASE]
at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:127) [spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) [spring-aop-5.1.10.RELEASE.jar:5.1.10.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) [spring-aop-5.1.10.RELEASE.jar:5.1.10.RELEASE]
at com.sun.proxy.$Proxy44.run(Unknown Source) [na:na]
at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.execute(JobLauncherCommandLineRunner.java:207) [spring-boot-autoconfigure-2.1.9.RELEASE.jar:2.1.9.RELEASE]
at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.executeLocalJobs(JobLauncherCommandLineRunner.java:181) [spring-boot-autoconfigure-2.1.9.RELEASE.jar:2.1.9.RELEASE]
at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.launchJobFromProperties(JobLauncherCommandLineRunner.java:168) [spring-boot-autoconfigure-2.1.9.RELEASE.jar:2.1.9.RELEASE]
at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.run(JobLauncherCommandLineRunner.java:163) [spring-boot-autoconfigure-2.1.9.RELEASE.jar:2.1.9.RELEASE]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:781) [spring-boot-2.1.9.RELEASE.jar:2.1.9.RELEASE]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:765) [spring-boot-2.1.9.RELEASE.jar:2.1.9.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:319) [spring-boot-2.1.9.RELEASE.jar:2.1.9.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.1.9.RELEASE.jar:2.1.9.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1204) [spring-boot-2.1.9.RELEASE.jar:2.1.9.RELEASE]
at com.bigzidane.example.springbatch.HelloBatch.main(HelloBatch.java:9) [classes/:na]
2019-10-05 14:42:40.759 INFO 11268 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : Job: [FlowJob: [name=processJob]] completed with the following parameters: [{run.id=1}] and the following status: [FAILED]
2019-10-05 14:42:40.764 INFO 11268 --- [ Thread-2] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2019-10-05 14:42:40.768 INFO 11268 --- [ Thread-2] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
Process finished with exit code 0
If you want to perform the validation at the reader level, you can use a ItemReadListener or by overriding FlatFileItemReader and calling the validation logic in doRead as shown by #Nghia Do.
Item validation is a typical use case for an item processor. If you use Spring Batch 4.1+, you can use the BeanValidatingItemProcessor in your chunk-oriented step. You can find an example here: https://docs.spring.io/spring-batch/4.1.x/reference/html/whatsnew.html#whatsNewBeanValidationApi

Spring boot - Messaging with RabbitMQ to listen message queue continuously

When I run the Messaging with RabbitMQ guide [I tried this demo application][1] , the listener only receive the message once (the runner send once and then exited). I hope the listener can continuously listen the message queue, how should I achieve it ?
the receiver code:
package hello;
import java.util.concurrent.CountDownLatch;
import org.springframework.stereotype.Component;
#Component
public class Receiver {
private CountDownLatch latch = new CountDownLatch(1);
public void receiveMessage(String message) {
System.out.println("Received <" + message + ">");
latch.countDown();
}
public CountDownLatch getLatch() {
return latch;
}
}
the runner code:
package hello;
import java.util.concurrent.TimeUnit;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
#Component
public class Runner implements CommandLineRunner {
private final RabbitTemplate rabbitTemplate;
private final Receiver receiver;
public Runner(Receiver receiver, RabbitTemplate rabbitTemplate) {
this.receiver = receiver;
this.rabbitTemplate = rabbitTemplate;
}
#Override
public void run(String... args) throws Exception {
System.out.println("Sending message...");
rabbitTemplate.convertAndSend(Application.topicExchangeName, "foo.bar.baz", "====1===========Hello from RabbitMQ!");
rabbitTemplate.convertAndSend(Application.topicExchangeName, "foo.bar.baz", "====2===========Hello from RabbitMQ!");
rabbitTemplate.convertAndSend(Application.topicExchangeName, "foo.bar.baz", "=====3==========Hello from RabbitMQ!");
receiver.getLatch().await(10000, TimeUnit.MILLISECONDS);
}
}
the application code:
ackage hello;
import hello.test.TestListener;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
#SpringBootApplication
public class Application {
static final String topicExchangeName = "spring-boot-exchange";
public static final String queueName = "spring-boot";
#Bean
Queue queue() {
return new Queue(queueName, false);
}
#Bean
TopicExchange exchange() {
return new TopicExchange(topicExchangeName);
}
#Bean
Binding binding(Queue queue, TopicExchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("foo.bar.#");
}
#Bean
SimpleMessageListenerContainer container(ConnectionFactory connectionFactory,
MessageListenerAdapter listenerAdapter) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.setQueueNames(queueName);
container.setMessageListener(listenerAdapter);
return container;
}
#Bean
MessageListenerAdapter listenerAdapter(Receiver receiver) {
return new MessageListenerAdapter(receiver, "receiveMessage");
}
public static void main(String[] args) throws InterruptedException {
SpringApplication.run(Application.class, args).close();
}
}
the log
[opuser#iZ25fprd8a9Z java]$ java -jar gs-messaging-rabbitmq-0.1.0.jar
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.1.RELEASE)
2019-01-10 09:40:53.846 INFO 412 --- [ main] hello.Application : Starting Application on iZ25fprd8a9Z with PID 412 (/data/workspace/test/java/gs-messaging-rabbitmq-0.1.0.jar started by opuser in /data/workspace/test/java)
2019-01-10 09:40:53.854 INFO 412 --- [ main] hello.Application : No active profile set, falling back to default profiles: default
2019-01-10 09:40:55.019 INFO 412 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.amqp.rabbit.annotation.RabbitBootstrapConfiguration' of type [org.springframework.amqp.rabbit.annotation.RabbitBootstrapConfiguration$$EnhancerBySpringCGLIB$$870d6481] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2019-01-10 09:40:56.047 INFO 412 --- [ main] o.s.a.r.c.CachingConnectionFactory : Attempting to connect to: [10.171.135.109:5672]
2019-01-10 09:40:56.145 INFO 412 --- [ main] o.s.a.r.c.CachingConnectionFactory : Created new connection: rabbitConnectionFactory#76f2b07d:0/SimpleConnection#49c43f4e [delegate=amqp://petmq#10.171.135.109:5672/, localPort= 41068]
2019-01-10 09:40:56.152 INFO 412 --- [ main] o.s.amqp.rabbit.core.RabbitAdmin : Auto-declaring a non-durable, auto-delete, or exclusive Queue (spring-boot) 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.
2019-01-10 09:40:56.244 INFO 412 --- [ main] hello.Application : Started Application in 3.116 seconds (JVM running for 4.001)
Sending message...
Received <====1===========Hello from RabbitMQ!>
Received <====2===========Hello from RabbitMQ!>
Received <=====3==========Hello from RabbitMQ!>
2019-01-10 09:40:56.269 INFO 412 --- [ main] o.s.a.r.l.SimpleMessageListenerContainer : Waiting for workers to finish.
2019-01-10 09:40:57.267 INFO 412 --- [ main] o.s.a.r.l.SimpleMessageListenerContainer : Successfully waited for workers to finish.
2019-01-10 09:40:57.272 INFO 412 --- [ main] o.s.a.r.l.SimpleMessageListenerContainer : Shutdown ignored - container is not active already
If you add the dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Your application will not close out.

Spring Cloud Kubernetes - Spring boot fails to start when config reload is enabled

I have this demo project which prints a label that is read from the configurations.
This is my main class:
#SpringBootApplication
#EnableDiscoveryClient
#RestController
public class DemoApplication {
private MyConfig config;
private DiscoveryClient discoveryClient;
#Autowired
public DemoApplication(MyConfig config, DiscoveryClient discoveryClient) {
this.config = config;
this.discoveryClient = discoveryClient;
}
#RequestMapping("/")
public String info() {
return config.getMessage();
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#RequestMapping("/services")
public String services() {
StringBuilder b = new StringBuilder();
discoveryClient.getServices().forEach((s) -> b.append(s).append(" , "));
return b.toString();
}
}
And the MyConfig class is:
#Configuration
#ConfigurationProperties(prefix = "bean")
public class MyConfig {
private String message = "a message that can be changed live";
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
The bootstrap.properties contain:
spring.application.name=demo
spring.cloud.kubernetes.config.name=demo
spring.cloud.kubernetes.config.enabled=true
spring.cloud.kubernetes.config.namespace=default
spring.cloud.kubernetes.reload.enabled=true
spring.cloud.kubernetes.reload.monitoring-config-maps=true
spring.cloud.kubernetes.reload.strategy=refresh
spring.cloud.kubernetes.reload.mode=event
management.endpoint.refresh.enabled=true
management.endpoints.web.exposure.include=*
And the dependencies in build.gradle:
dependencies {
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-actuator")
compile("org.springframework.cloud:spring-cloud-starter-kubernetes:+")
compile("org.springframework.cloud:spring-cloud-starter-kubernetes-config:+")
testCompile('org.springframework.boot:spring-boot-starter-test')
runtime("org.springframework.boot:spring-boot-properties-migrator")
}
I'm creating the ConfigMap with kubectl create -f configmap-demo.yml being the content:
apiVersion: v1
kind: ConfigMap
metadata:
name: demo
data:
bean.message: This is an info from k8
When deploying in Kubernetes I get the following error on Spring Boot startup:
2019-01-02 13:41:41.462 INFO 1 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'configurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$e13002af] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.1.RELEASE)
2019-01-02 13:41:41.940 INFO 1 --- [ main] b.c.PropertySourceBootstrapConfiguration : Located property source: ConfigMapPropertySource {name='configmap.demo.default'}
2019-01-02 13:41:41.942 INFO 1 --- [ main] b.c.PropertySourceBootstrapConfiguration : Located property source: SecretsPropertySource {name='secrets.demo.default'}
2019-01-02 13:41:42.030 INFO 1 --- [ main] com.example.demo.DemoApplication : The following profiles are active: kubernetes
2019-01-02 13:41:43.391 INFO 1 --- [ main] o.s.cloud.context.scope.GenericScope : BeanFactory id=416ee750-8ebb-365d-9114-12b51acaa1e0
2019-01-02 13:41:43.490 INFO 1 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$e13002af] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2019-01-02 13:41:43.917 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2019-01-02 13:41:43.952 INFO 1 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2019-01-02 13:41:43.953 INFO 1 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/9.0.13
2019-01-02 13:41:43.969 INFO 1 --- [ main] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/usr/lib/jvm/java-1.8-openjdk/jre/lib/amd64/server:/usr/lib/jvm/java-1.8-openjdk/jre/lib/amd64:/usr/lib/jvm/java-1.8-openjdk/jre/../lib/amd64:/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib]
2019-01-02 13:41:44.156 INFO 1 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2019-01-02 13:41:44.157 INFO 1 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2033 ms
2019-01-02 13:41:44.957 INFO 1 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2019-01-02 13:41:45.353 WARN 1 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'propertyChangeWatcher' defined in class path resource [org/springframework/cloud/kubernetes/config/reload/ConfigReloadAutoConfiguration$ConfigReloadAutoConfigurationBeans.class]: Unsatisfied dependency expressed through method 'propertyChangeWatcher' parameter 1; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'configurationUpdateStrategy' defined in class path resource [org/springframework/cloud/kubernetes/config/reload/ConfigReloadAutoConfiguration$ConfigReloadAutoConfigurationBeans.class]: Unsatisfied dependency expressed through method 'configurationUpdateStrategy' parameter 2; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.cloud.context.restart.RestartEndpoint' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
2019-01-02 13:41:45.358 INFO 1 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
2019-01-02 13:41:45.370 INFO 1 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2019-01-02 13:41:45.398 INFO 1 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-01-02 13:41:45.612 ERROR 1 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 2 of method configurationUpdateStrategy in org.springframework.cloud.kubernetes.config.reload.ConfigReloadAutoConfiguration$ConfigReloadAutoConfigurationBeans required a bean of type 'org.springframework.cloud.context.restart.RestartEndpoint' that could not be found.
The following candidates were found but could not be injected:
- Bean method 'restartEndpoint' in 'RestartEndpointWithIntegrationConfiguration' not loaded because #ConditionalOnClass did not find required class 'org.springframework.integration.monitor.IntegrationMBeanExporter'
- Bean method 'restartEndpointWithoutIntegration' in 'RestartEndpointWithoutIntegrationConfiguration' not loaded because #ConditionalOnEnabledEndpoint no property management.endpoint.restart.enabled found so using endpoint default
Action:
Consider revisiting the entries above or defining a bean of type 'org.springframework.cloud.context.restart.RestartEndpoint' in your configuration.
If I set spring.cloud.kubernetes.reload.enabled to false everything works and the configmap is read and put to use. Now my goal is to reload the configuration if the configmap changes but get the exception seen above. I can invoke /actuator/refresh manually so I don't think it is the lack of the availability for the refresh endpoint.
I created a demo project with all included at https://drive.google.com/open?id=1QbP8vePALLZ2hWQJArnyxrzSySuXHKiz .
It starts if you set management.endpoint.restart.enabled=true
The message tells you that it can't load a RestartEndpoint bean. None was created because there's two ways it could be loaded and nether was satisfied:
Bean method 'restartEndpoint' in 'RestartEndpointWithIntegrationConfiguration' not loaded because #ConditionalOnClass did not find required class 'org.springframework.integration.monitor.IntegrationMBeanExporter'
Well you're not using spring integration so I guess you don't want this path - you want the other one.
Bean method 'restartEndpointWithoutIntegration' in 'RestartEndpointWithoutIntegrationConfiguration' not loaded because #ConditionalOnEnabledEndpoint no property management.endpoint.restart.enabled found so using endpoint default
So we need to set management.endpoint.restart.enabled=true, which is also set in the official reload example project. Without setting this the RestartEndpoint bean that we require will not be loaded.
In the application.properties add these two lines:
management.endpoint.restart.enabled=true
spring.jmx.enabled=true

RabbitMQ Failed to declare queue and Listener is not able to get queue on server

I have spring boot rabbitmq application where i have to send an Employee object to queue. Then i have set up a listener application. Do some processing on employee object and put this object in call back queue.
For this, i have created below objects in my appication.
Created ConnectionFactory.
Created RabbitAdmin object using ConnectionFactory..
Request Queue.
Callback Queue.
Direct Exchange.
Request Queue Binding.
Callback Queue Binding.
MessageConverter.
RabbitTemplate object.
And finally object of SimpleMessageListenerContainer.
My Application files looks like below.
application.properties
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.virtual-host=foo
emp.rabbitmq.directexchange=EMP_EXCHANGE1
emp.rabbitmq.requestqueue=EMP_QUEUE1
emp.rabbitmq.routingkey=EMP_ROUTING_KEY1
MainClass.java
package com.employee;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class MainClass {
public static void main(String[] args) {
SpringApplication.run(
MainClass.class, args);
}
}
ApplicationContextProvider.java
package com.employee.config;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
public class ApplicationContextProvider implements ApplicationContextAware {
private static ApplicationContext context;
public ApplicationContext getApplicationContext(){
return context;
}
#Override
public void setApplicationContext(ApplicationContext arg0) throws BeansException {
context = arg0;
}
public Object getBean(String name){
return context.getBean(name, Object.class);
}
public void addBean(String beanName, Object beanObject){
ConfigurableListableBeanFactory beanFactory = ((ConfigurableApplicationContext)context).getBeanFactory();
beanFactory.registerSingleton(beanName, beanObject);
}
public void removeBean(String beanName){
BeanDefinitionRegistry reg = (BeanDefinitionRegistry) context.getAutowireCapableBeanFactory();
reg.removeBeanDefinition(beanName);
}
}
Constants.java
package com.employee.constant;
public class Constants {
public static final String CALLBACKQUEUE = "_CBQ";
}
Employee.java
package com.employee.model;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
#JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "#id", scope = Employee.class)
public class Employee {
private String empName;
private String empId;
private String changedValue;
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public String getEmpId() {
return empId;
}
public void setEmpId(String empId) {
this.empId = empId;
}
public String getChangedValue() {
return changedValue;
}
public void setChangedValue(String changedValue) {
this.changedValue = changedValue;
}
}
EmployeeProducerInitializer.java
package com.employee.config;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import com.employee.constant.Constants;
import com.employee.service.EmployeeResponseReceiver;
#Configuration
#EnableAutoConfiguration
#ComponentScan(value="com.en.*")
public class EmployeeProducerInitializer {
#Value("${emp.rabbitmq.requestqueue}")
String requestQueueName;
#Value("${emp.rabbitmq.directexchange}")
String directExchange;
#Value("${emp.rabbitmq.routingkey}")
private String requestRoutingKey;
#Autowired
private ConnectionFactory rabbitConnectionFactory;
#Bean
ApplicationContextProvider applicationContextProvider(){
System.out.println("inside app ctx provider");
return new ApplicationContextProvider();
};
#Bean
RabbitAdmin rabbitAdmin(){
System.out.println("inside rabbit admin");
return new RabbitAdmin(rabbitConnectionFactory);
};
#Bean
Queue empRequestQueue() {
System.out.println("inside request queue");
return new Queue(requestQueueName, true);
}
#Bean
Queue empCallBackQueue() {
System.out.println("inside call back queue");
return new Queue(requestQueueName + Constants.CALLBACKQUEUE, true);
}
#Bean
DirectExchange empDirectExchange() {
System.out.println("inside exchange");
return new DirectExchange(directExchange);
}
#Bean
Binding empRequestBinding() {
System.out.println("inside request binding");
return BindingBuilder.bind(empRequestQueue()).to(empDirectExchange()).with(requestRoutingKey);
}
#Bean
Binding empCallBackBinding() {
return BindingBuilder.bind(empCallBackQueue()).to(empDirectExchange()).with(requestRoutingKey + Constants.CALLBACKQUEUE);
}
#Bean
public MessageConverter jsonMessageConverter(){
System.out.println("inside json msg converter");
return new Jackson2JsonMessageConverter();
}
#Bean
public RabbitTemplate empFixedReplyQRabbitTemplate() {
System.out.println("inside rabbit template");
RabbitTemplate template = new RabbitTemplate(this.rabbitConnectionFactory);
template.setExchange(empDirectExchange().getName());
template.setRoutingKey(requestRoutingKey);
template.setMessageConverter(jsonMessageConverter());
template.setReceiveTimeout(100000);
template.setReplyTimeout(100000);
return template;
}
#Bean
public SimpleMessageListenerContainer empReplyListenerContainer() {
System.out.println("inside listener");
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
try{
container.setConnectionFactory(this.rabbitConnectionFactory);
container.setQueues(empCallBackQueue());
container.setMessageListener(new EmployeeResponseReceiver());
container.setMessageConverter(jsonMessageConverter());
container.setConcurrentConsumers(10);
container.setMaxConcurrentConsumers(20);
container.start();
}catch(Exception e){
e.printStackTrace();
}finally{
System.out.println("inside listener finally");
}
return container;
}
#Autowired
#Qualifier("empReplyListenerContainer")
private SimpleMessageListenerContainer empReplyListenerContainer;
}
EmployeeResponseReceiver.java
package com.employee.service;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.stereotype.Component;
import com.employee.config.ApplicationContextProvider;
import com.employee.model.Employee;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rabbitmq.client.Channel;
#Component
#EnableAutoConfiguration
public class EmployeeResponseReceiver implements ChannelAwareMessageListener {
ApplicationContextProvider applicationContextProvider = new ApplicationContextProvider();
String msg = null;
ObjectMapper mapper = new ObjectMapper();
Employee employee = null;
#Override
public void onMessage(Message message, Channel arg1) throws Exception {
try {
msg = new String(message.getBody());
System.out.println("Received Message : " + msg);
employee = mapper.readValue(msg, Employee.class);
} catch (Exception e) {
e.printStackTrace();
}
}
}
The problem is whenever i start my application, i get below exceptions.
2018-03-17 14:18:36.695 INFO 12472 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2018-03-17 14:18:36.696 INFO 12472 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 5060 ms
2018-03-17 14:18:37.004 INFO 12472 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2018-03-17 14:18:37.010 INFO 12472 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-03-17 14:18:37.010 INFO 12472 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-03-17 14:18:37.011 INFO 12472 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-03-17 14:18:37.011 INFO 12472 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
inside listener
inside call back queue
inside json msg converter
2018-03-17 14:18:37.576 INFO 12472 --- [cTaskExecutor-8] o.s.a.r.c.CachingConnectionFactory : Created new connection: SimpleConnection#3d31af39 [delegate=amqp://guest#127.0.0.1:5672/foo, localPort= 50624]
2018-03-17 14:18:37.654 WARN 12472 --- [cTaskExecutor-7] o.s.a.r.listener.BlockingQueueConsumer : Failed to declare queue:EMP_QUEUE1_CBQ
2018-03-17 14:18:37.655 WARN 12472 --- [cTaskExecutor-6] o.s.a.r.listener.BlockingQueueConsumer : Failed to declare queue:EMP_QUEUE1_CBQ
2018-03-17 14:18:37.655 WARN 12472 --- [cTaskExecutor-5] o.s.a.r.listener.BlockingQueueConsumer : Failed to declare queue:EMP_QUEUE1_CBQ
2018-03-17 14:18:37.655 WARN 12472 --- [cTaskExecutor-3] o.s.a.r.listener.BlockingQueueConsumer : Failed to declare queue:EMP_QUEUE1_CBQ
2018-03-17 14:18:37.657 WARN 12472 --- [cTaskExecutor-1] o.s.a.r.listener.BlockingQueueConsumer : Failed to declare queue:EMP_QUEUE1_CBQ
2018-03-17 14:18:37.658 WARN 12472 --- [cTaskExecutor-8] o.s.a.r.listener.BlockingQueueConsumer : Failed to declare queue:EMP_QUEUE1_CBQ
2018-03-17 14:18:37.661 WARN 12472 --- [cTaskExecutor-2] o.s.a.r.listener.BlockingQueueConsumer : Failed to declare queue:EMP_QUEUE1_CBQ
2018-03-17 14:18:37.660 WARN 12472 --- [cTaskExecutor-4] o.s.a.r.listener.BlockingQueueConsumer : Failed to declare queue:EMP_QUEUE1_CBQ
2018-03-17 14:18:37.661 WARN 12472 --- [cTaskExecutor-9] o.s.a.r.listener.BlockingQueueConsumer : Failed to declare queue:EMP_QUEUE1_CBQ
2018-03-17 14:18:37.666 WARN 12472 --- [TaskExecutor-10] o.s.a.r.listener.BlockingQueueConsumer : Failed to declare queue:EMP_QUEUE1_CBQ
2018-03-17 14:18:37.667 WARN 12472 --- [cTaskExecutor-2] o.s.a.r.listener.BlockingQueueConsumer : Queue declaration failed; retries left=3
org.springframework.amqp.rabbit.listener.BlockingQueueConsumer$DeclarationException: Failed to declare queue(s):[EMP_QUEUE1_CBQ]
at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.attemptPassiveDeclarations(BlockingQueueConsumer.java:636) ~[spring-rabbit-1.7.2.RELEASE.jar:na]
at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:535) ~[spring-rabbit-1.7.2.RELEASE.jar:na]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1389) [spring-rabbit-1.7.2.RELEASE.jar:na]
at java.lang.Thread.run(Unknown Source) [na:1.8.0_151]
Caused by: java.io.IOException: null
at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:105) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:101) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:123) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.ChannelN.queueDeclarePassive(ChannelN.java:992) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.ChannelN.queueDeclarePassive(ChannelN.java:50) ~[amqp-client-4.0.2.jar:4.0.2]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_151]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_151]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_151]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_151]
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory$CachedChannelInvocationHandler.invoke(CachingConnectionFactory.java:955) ~[spring-rabbit-1.7.2.RELEASE.jar:na]
at com.sun.proxy.$Proxy58.queueDeclarePassive(Unknown Source) ~[na:na]
at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.attemptPassiveDeclarations(BlockingQueueConsumer.java:615) ~[spring-rabbit-1.7.2.RELEASE.jar:na]
... 3 common frames omitted
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no queue 'EMP_QUEUE1_CBQ' in vhost 'foo', class-id=50, method-id=10)
at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:66) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:32) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:366) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:229) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:117) ~[amqp-client-4.0.2.jar:4.0.2]
... 12 common frames omitted
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no queue 'EMP_QUEUE1_CBQ' in vhost 'foo', class-id=50, method-id=10)
at com.rabbitmq.client.impl.ChannelN.asyncShutdown(ChannelN.java:505) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.ChannelN.processAsync(ChannelN.java:336) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.AMQChannel.handleCompleteInboundCommand(AMQChannel.java:143) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.AMQChannel.handleFrame(AMQChannel.java:90) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.AMQConnection.readFrame(AMQConnection.java:634) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.AMQConnection.access$300(AMQConnection.java:47) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:572) ~[amqp-client-4.0.2.jar:4.0.2]
... 1 common frames omitted
2018-03-17 14:08:36.689 WARN 11076 --- [cTaskExecutor-4] o.s.a.r.listener.BlockingQueueConsumer : Failed to declare queue:EMP_QUEUE1_CBQ
2018-03-17 14:08:36.695 ERROR 11076 --- [cTaskExecutor-4] o.s.a.r.l.SimpleMessageListenerContainer : Consumer received fatal exception on startup
org.springframework.amqp.rabbit.listener.QueuesNotAvailableException: Cannot prepare queue for listener. Either the queue doesn't exist or the broker will not allow us to use it.
at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:563) ~[spring-rabbit-1.7.2.RELEASE.jar:na]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1389) ~[spring-rabbit-1.7.2.RELEASE.jar:na]
at java.lang.Thread.run(Unknown Source) [na:1.8.0_151]
Caused by: org.springframework.amqp.rabbit.listener.BlockingQueueConsumer$DeclarationException: Failed to declare queue(s):[EMP_QUEUE1_CBQ]
at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.attemptPassiveDeclarations(BlockingQueueConsumer.java:636) ~[spring-rabbit-1.7.2.RELEASE.jar:na]
at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:535) ~[spring-rabbit-1.7.2.RELEASE.jar:na]
... 2 common frames omitted
Caused by: java.io.IOException: null
at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:105) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:101) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:123) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.ChannelN.queueDeclarePassive(ChannelN.java:992) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.ChannelN.queueDeclarePassive(ChannelN.java:50) ~[amqp-client-4.0.2.jar:4.0.2]
at sun.reflect.GeneratedMethodAccessor27.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_151]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_151]
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory$CachedChannelInvocationHandler.invoke(CachingConnectionFactory.java:955) ~[spring-rabbit-1.7.2.RELEASE.jar:na]
at com.sun.proxy.$Proxy58.queueDeclarePassive(Unknown Source) ~[na:na]
at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.attemptPassiveDeclarations(BlockingQueueConsumer.java:615) ~[spring-rabbit-1.7.2.RELEASE.jar:na]
... 3 common frames omitted
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no queue 'EMP_QUEUE1_CBQ' in vhost 'foo', class-id=50, method-id=10)
at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:66) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:32) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:366) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:229) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:117) ~[amqp-client-4.0.2.jar:4.0.2]
... 11 common frames omitted
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no queue 'EMP_QUEUE1_CBQ' in vhost 'foo', class-id=50, method-id=10)
at com.rabbitmq.client.impl.ChannelN.asyncShutdown(ChannelN.java:505) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.ChannelN.processAsync(ChannelN.java:336) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.AMQChannel.handleCompleteInboundCommand(AMQChannel.java:143) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.AMQChannel.handleFrame(AMQChannel.java:90) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.AMQConnection.readFrame(AMQConnection.java:634) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.AMQConnection.access$300(AMQConnection.java:47) ~[amqp-client-4.0.2.jar:4.0.2]
at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:572) ~[amqp-client-4.0.2.jar:4.0.2]
... 1 common frames omitted
2018-03-17 14:08:36.697 INFO 11076 --- [TaskExecutor-10] o.s.a.r.l.SimpleMessageListenerContainer : Successfully waited for workers to finish.
2018-03-17 14:08:36.699 INFO 11076 --- [cTaskExecutor-5] o.s.a.r.l.SimpleMessageListenerContainer : Successfully waited for workers to finish.
2018-03-17 14:08:36.700 INFO 11076 --- [cTaskExecutor-1] o.s.a.r.l.SimpleMessageListenerContainer : Successfully waited for workers to finish.
2018-03-17 14:08:36.701 INFO 11076 --- [cTaskExecutor-3] o.s.a.r.l.SimpleMessageListenerContainer : Successfully waited for workers to finish.
2018-03-17 14:08:36.700 INFO 11076 --- [cTaskExecutor-2] o.s.a.r.l.SimpleMessageListenerContainer : Successfully waited for workers to finish.
2018-03-17 14:08:36.702 INFO 11076 --- [cTaskExecutor-7] o.s.a.r.l.SimpleMessageListenerContainer : Successfully waited for workers to finish.
2018-03-17 14:08:36.765 ERROR 11076 --- [cTaskExecutor-8] o.s.a.r.l.SimpleMessageListenerContainer : Stopping container from aborted consumer
2018-03-17 14:08:36.766 ERROR 11076 --- [cTaskExecutor-6] o.s.a.r.l.SimpleMessageListenerContainer : Stopping container from aborted consumer
2018-03-17 14:08:36.779 ERROR 11076 --- [cTaskExecutor-9] o.s.a.r.l.SimpleMessageListenerContainer : Stopping container from aborted consumer
2018-03-17 14:08:36.791 ERROR 11076 --- [cTaskExecutor-4] o.s.a.r.l.SimpleMessageListenerContainer : Stopping container from aborted consumer
inside app ctx provider
inside rabbit admin
inside exchange
inside request queue
inside request binding
inside rabbit template
2018-03-17 14:08:38.978 INFO 11076 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for #ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext#33b37288: startup date [Sat Mar 17 14:08:16 IST 2018]; root of context hierarchy
2018-03-17 14:08:39.395 INFO 11076 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2018-03-17 14:08:39.398 INFO 11076 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2018-03-17 14:08:39.663 INFO 11076 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-03-17 14:08:39.663 INFO 11076 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-03-17 14:08:39.826 INFO 11076 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-03-17 14:08:40.648 INFO 11076 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2018-03-17 14:08:40.677 INFO 11076 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Bean with name 'rabbitConnectionFactory' has been autodetected for JMX exposure
2018-03-17 14:08:40.685 INFO 11076 --- [ 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]
2018-03-17 14:08:40.746 INFO 11076 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase -2147482648
2018-03-17 14:08:40.747 INFO 11076 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 2147483647
2018-03-17 14:08:41.258 INFO 11076 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2018-03-17 14:08:41.270 INFO 11076 --- [ main] com.employee.MainClass : Started MainClass in 26.141 seconds (JVM running for 28.02)
Can anybody help me resolving my issue? As per my understanding, when object of SimpleMessageListenerContainer is being created, callback queue is not created on rabbitmq server. I tried declaring queue using RabbitAdmin object, but then execution stops and nothing goes ahead. This problem was not there when i was declaring queue in default virtual host. But when i added virtual host foo all of it sudden stopped working. You can replicate this issue using above code. I have pasted all my code. Kindly let me know if anything else is to be posted.
Interesting point is even if i am getting this exceptions, my application is up and running. That means somehow my callback queue is created and object of SimpleMessageListenerContainer gets the queue. I read somewhere that, when queue is created, my SimpleMessageListenerContainer object will listen to it.
Please help me resolving this issue.
This problem was not there when i was declaring queue in default virtual host. But when i added virtual host foo all of it sudden stopped working.
Does the user that accesses the new virtual host have configure permissions? Configure permissions are required to declare queues.
A RabbitAdmin is required to declare the queues/bindings; the container only does a passive declaration to check the queue is present.
EDIT
container.start();
You must not start() the container within a bean definition. The application context will do that after the application context is completely built, if the container's autoStartUp is true (default).
It is clear from your logs that the container is starting too early - before the other beans (admin, queue etc) have been declared.

Resources