There are tons of examples where java code is being used to configure pure rabbit, but spring boot related documentation is another story.
My requirement is pretty basic - Single queue, Single exchange, One dead-letter queue with predefined names. Some HA policy. Deployed to pivotal cloud-foundry.
The app should use cloud connection factory, so I don't have to specify connection info.
The app should create queue/exchange if they don't exist.
I need a controller that can use rabbitTemplate to send msgs.
I need a listener to process those messages, in multiple consumer threads.
I have tried to do properties-only approach. And I have tried tons of beans to do this. For some reason it doesn't want to connect to cloud service!
I am using spring boot app and running it in pivotal cloud foundry
Code
#Configuration
#EnableRabbit
#Profile("cloud")
#Slf4j
public class RabbitMQConfig extends AbstractCloudConfig {
final static String MAIN_QUEUE_NAME = "pricing";
private final static String QUEUE_EXCHANGE_NAME = "pricing-exchange";
private final static String DEAD_LETTER_QUEUE_NAME = "pricing-dl";
#Autowired
RabbitProperties rabbitProperties;
#Bean("pricingQueue")
#Primary
public Queue pricingQueue() {
return QueueBuilder.durable(MAIN_QUEUE_NAME)
.withArgument("x-dead-letter-exchange", "")
.withArgument("x-dead-letter-routing-key", DEAD_LETTER_QUEUE_NAME)
.withArgument("x-queue-master-locator", "min-masters")
.build();
}
#Bean
public Queue deadLetterQueue() {
return QueueBuilder.durable(DEAD_LETTER_QUEUE_NAME)
.withArgument("x-queue-master-locator", "min-masters")
.build();
}
#Bean
public DirectExchange exchange() {
return new DirectExchange(QUEUE_EXCHANGE_NAME);
}
#Bean
public Binding pricingBinding(#Qualifier("pricingQueue") Queue pricingQueue,
DirectExchange exchange) {
return BindingBuilder.bind(pricingQueue).to(exchange).with(MAIN_QUEUE_NAME);
}
#Bean
public MessageConverter jsonMessageConverter() {
return new Jackson2JsonMessageConverter();
}
}
I think this is happening because spring boot created the listener container and not me
Error
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.getSingleton:213]- Creating shared instance of singleton bean 'org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.getSingleton:213]- Creating shared instance of singleton bean 'management.health.status-org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorProperties'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.createArgumentArray:777]- Autowiring by type from bean name 'org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration' via constructor to bean named 'management.health.status-org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorProperties'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.getSingleton:213]- Creating shared instance of singleton bean 'healthIndicatorRegistry'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.createArgumentArray:777]- Autowiring by type from bean name 'healthIndicatorRegistry' via factory method to bean named 'org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext#6483f5ae'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.getSingleton:213]- Creating shared instance of singleton bean 'rabbitHealthIndicator'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.getSingleton:213]- Creating shared instance of singleton bean 'org.springframework.boot.actuate.autoconfigure.amqp.RabbitHealthIndicatorAutoConfiguration'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.getSingleton:213]- Creating shared instance of singleton bean 'rabbitTemplate'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.getSingleton:213]- Creating shared instance of singleton bean 'org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration$RabbitTemplateConfiguration'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.getSingleton:213]- Creating shared instance of singleton bean 'spring.rabbitmq-org.springframework.boot.autoconfigure.amqp.RabbitProperties'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.createArgumentArray:777]- Autowiring by type from bean name 'org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration$RabbitTemplateConfiguration' via constructor to bean named 'spring.rabbitmq-org.springframework.boot.autoconfigure.amqp.RabbitProperties'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.getSingleton:213]- Creating shared instance of singleton bean 'rabbitConnectionFactory'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.getSingleton:213]- Creating shared instance of singleton bean 'org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration$RabbitConnectionFactoryCreator'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.createArgumentArray:777]- Autowiring by type from bean name 'rabbitConnectionFactory' via factory method to bean named 'spring.rabbitmq-org.springframework.boot.autoconfigure.amqp.RabbitProperties'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.createArgumentArray:777]- Autowiring by type from bean name 'rabbitTemplate' via factory method to bean named 'rabbitConnectionFactory'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.getSingleton:213]- Creating shared instance of singleton bean 'jsonMessageConverter'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.getSingleton:213]- Creating shared instance of singleton bean 'rabbitMQConfig'
...
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.createArgumentArray:777]- Autowiring by type from bean name 'viewResolver' via factory method to bean named 'org.springframework.beans.factory.support.DefaultListableBeanFactory#1dde4cb2'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.getSingleton:213]- Creating shared instance of singleton bean 'amqpAdmin'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.createArgumentArray:777]- Autowiring by type from bean name 'amqpAdmin' via factory method to bean named 'rabbitConnectionFactory'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.getSingleton:213]- Creating shared instance of singleton bean 'org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration$MessagingTemplateConfiguration'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.getSingleton:213]- Creating shared instance of singleton bean 'rabbitMessagingTemplate'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.createArgumentArray:777]- Autowiring by type from bean name 'rabbitMessagingTemplate' via factory method to bean named 'rabbitTemplate'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.getSingleton:213]- Creating shared instance of singleton bean 'org.springframework.boot.autoconfigure.amqp.RabbitAnnotationDrivenConfiguration'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.createArgumentArray:777]- Autowiring by type from bean name 'org.springframework.boot.autoconfigure.amqp.RabbitAnnotationDrivenConfiguration' via constructor to bean named 'spring.rabbitmq-org.springframework.boot.autoconfigure.amqp.RabbitProperties'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.getSingleton:213]- Creating shared instance of singleton bean 'simpleRabbitListenerContainerFactoryConfigurer'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.getSingleton:213]- Creating shared instance of singleton bean 'rabbitListenerContainerFactory'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.createArgumentArray:777]- Autowiring by type from bean name 'rabbitListenerContainerFactory' via factory method to bean named 'simpleRabbitListenerContainerFactoryConfigurer'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.createArgumentArray:777]- Autowiring by type from bean name 'rabbitListenerContainerFactory' via factory method to bean named 'rabbitConnectionFactory'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.getSingleton:213]- Creating shared instance of singleton bean 'directRabbitListenerContainerFactoryConfigurer'
...
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.getSingleton:213]- Creating shared instance of singleton bean 'org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration'
[main] [DEBUG] [org.springframework.beans.factory.support.DefaultListableBeanFactory.getSingleton:213]- Creating shared instance of singleton bean 'management.server-org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties'
[main] [DEBUG] [org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.:264]- Inferred argument type for public void com.gm.gsmc.pricing.messenger.service.PricingMessageListener.handleMessage(com.gm.gsmc.pricing.domain.queue.QueueMessage) is class com.gm.gsmc.pricing.domain.queue.QueueMessage
[main] [DEBUG] [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.setConcurrentConsumers:166]- Changing consumers from 1 to 5
[main] [DEBUG] [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.start:1293]- Starting Rabbit listener container.
[main] [INFO ] [org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createBareConnection:482]- Attempting to connect to: [localhost:5672]
[main] [INFO ] [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.checkMismatchedQueues:1713]- Broker not available; cannot force queue declarations during start: java.net.ConnectException: Connection refused (Connection refused)
[org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-1] [INFO ] [org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createBareConnection:482]- Attempting to connect to: [localhost:5672]
[org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-1] [ERROR] [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.redeclareElementsIfNecessary:1764]- Failed to check/redeclare auto-delete queue(s). java.net.ConnectException: Connection refused (Connection refused)\n at java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:1.8.0_212]\n at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[na:1.8.0_212]\n at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[na:1.8.0_212]\n at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[na:1.8.0_212]\n at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.8.0_212]\n at java.net.Socket.connect(Socket.java:589) ~[na:1.8.0_212]\n at com.rabbitmq.client.impl.SocketFrameHandlerFactory.create(SocketFrameHandlerFactory.java:60) ~[amqp-client-5.4.3.jar!/:5.4.3]\n at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1102) ~[amqp-client-5.4.3.jar!/:5.4.3]\n at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1054) ~[amqp-client-5.4.3.jar!/:5.4.3]\n at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:484) ~[spring-rabbit-2.1.8.RELEASE.jar!/:2.1.8.RELEASE]\n ... 11 common frames omitted\nWrapped by: org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused (Connection refused)\n at org.springframework.amqp.rabbit.support.RabbitExceptionTranslator.convertRabbitAccessException(RabbitExceptionTranslator.java:62) ~[spring-rabbit-2.1.8.RELEASE.jar!/:2.1.8.RELEASE]\n at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:530) ~[spring-rabbit-2.1.8.RELEASE.jar!/:2.1.8.RELEASE]\n at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createConnection(CachingConnectionFactory.java:702) ~[spring-rabbit-2.1.8.RELEASE.jar!/:2.1.8.RELEASE]\n at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.createConnection(ConnectionFactoryUtils.java:214) ~[spring-rabbit-2.1.8.RELEASE.jar!/:2.1.8.RELEASE]\n at org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:2076) ~[spring-rabbit-2.1.8.RELEASE.jar!/:2.1.8.RELEASE]\n at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:2050) ~[spring-rabbit-2.1.8.RELEASE.jar!/:2.1.8.RELEASE]\n at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:2030) ~[spring-rabbit-2.1.8.RELEASE.jar!/:2.1.8.RELEASE]\n at org.springframework.amqp.rabbit.core.RabbitAdmin.getQueueProperties(RabbitAdmin.java:403) ~[spring-rabbit-2.1.8.RELEASE.jar!/:2.1.8.RELEASE]\n at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.attemptDeclarations(AbstractMessageListenerContainer.java:1777) ~[spring-rabbit-2.1.8.RELEASE.jar!/:2.1.8.RELEASE]\n at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.redeclareElementsIfNecessary(AbstractMessageListenerContainer.java:1758) ~[spring-rabbit-2.1.8.RELEASE.jar!/:2.1.8.RELEASE]\n at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.initialize(SimpleMessageListenerContainer.java:1195) [spring-rabbit-2.1.8.RELEASE.jar!/:2.1.8.RELEASE]\n at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1041) [spring-rabbit-2.1.8.RELEASE.jar!/:2.1.8.RELEASE]\n at java.lang.Thread.run(Thread.java:748) [na:1.8.0_212]\n
I am not sure why you have those amqpAdmin calls in your bean definitions (although they are commented out). You must NEVER talk to the broker in a bean definition - it's too early in the lifecycle.
The error in the first log leads me to believe that was not commented out. That log looks truncated too - there should be Caused by parts. You should never truncate a log when asking a question. A partial stack trace is useless.
Factory method 'msgQueueBinding' threw exception; nested exception is org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused (Connection refused)
This clearly shows an attempt to connect from the msgQueueBinding method.
The following logs show the queue/exchange/binding being successfully declared when the listener starts.
I am guessing your admin calls are happening before the cloud code has replaced the connection factory bean definition.
Thanks for the pointers Gary
This is basically the config that "works"
If I take RabbitTemplate or Container Factory off, I start seeing errors
I took some code from RabbitAutoConfiguration and did my best to read the same yml and use the properties in the beans I create
#Configuration
#EnableRabbit
#Profile("cloud")
#Slf4j
public class RabbitMQConfig extends AbstractCloudConfig {
final static String MAIN_QUEUE_NAME = "pricing";
private final static String QUEUE_EXCHANGE_NAME = "pricing-exchange";
private final static String DEAD_LETTER_QUEUE_NAME = "pricing-dl";
#Autowired
RabbitProperties rabbitProperties;
private void debug(String step) {
CachingConnectionFactory connectionFactory = (CachingConnectionFactory) connectionFactory().rabbitConnectionFactory();
log.info("===> debug connection with {} {} ", step, connectionFactory.getClass().getName());
log.info("host {}", connectionFactory.getHost());
log.info("port {}", connectionFactory.getPort());
log.info("vh {}", connectionFactory.getVirtualHost());
log.info("user {}", connectionFactory.getUsername());
log.info("Auto recovery {}", connectionFactory.getRabbitConnectionFactory().isAutomaticRecoveryEnabled());
log.info("RabbitProperties {}", ToStringBuilder.reflectionToString(rabbitProperties));
}
#SuppressWarnings("DuplicatedCode")
#Bean
public RabbitTemplate rabbitTemplate(MessageConverter messageConverter) {
debug("rabbitTemplate");
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory().rabbitConnectionFactory());
rabbitTemplate.setMessageConverter(messageConverter);
if (rabbitProperties != null) {
RabbitProperties.Template properties = this.rabbitProperties.getTemplate();
PropertyMapper map = PropertyMapper.get();
if (properties.getRetry().isEnabled()) {
rabbitTemplate.setRetryTemplate(createRetryTemplate(properties.getRetry()));
}
map.from(properties::getReceiveTimeout).whenNonNull().as(Duration::toMillis)
.to(rabbitTemplate::setReceiveTimeout);
map.from(properties::getReplyTimeout).whenNonNull().as(Duration::toMillis).to(rabbitTemplate::setReplyTimeout);
map.from(properties::getExchange).to(rabbitTemplate::setExchange);
map.from(properties::getRoutingKey).to(rabbitTemplate::setRoutingKey);
map.from(properties::getDefaultReceiveQueue).whenNonNull().to(rabbitTemplate::setDefaultReceiveQueue);
}
return rabbitTemplate;
}
private RetryTemplate createRetryTemplate(RabbitProperties.Retry properties) {
PropertyMapper map = PropertyMapper.get();
RetryTemplate template = new RetryTemplate();
SimpleRetryPolicy policy = new SimpleRetryPolicy();
map.from(properties::getMaxAttempts).to(policy::setMaxAttempts);
template.setRetryPolicy(policy);
ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();
map.from(properties::getInitialInterval).whenNonNull().as(Duration::toMillis)
.to(backOffPolicy::setInitialInterval);
map.from(properties::getMultiplier).to(backOffPolicy::setMultiplier);
map.from(properties::getMaxInterval).whenNonNull().as(Duration::toMillis).to(backOffPolicy::setMaxInterval);
template.setBackOffPolicy(backOffPolicy);
return template;
}
#Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
debug("rabbit listener");
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory().rabbitConnectionFactory());
factory.setMessageConverter(jsonMessageConverter());
factory.setAcknowledgeMode(AcknowledgeMode.AUTO);
factory.setConcurrentConsumers(rabbitProperties.getListener().getSimple().getConcurrency());
factory.setMaxConcurrentConsumers(rabbitProperties.getListener().getSimple().getMaxConcurrency());
factory.setPrefetchCount(rabbitProperties.getListener().getSimple().getPrefetch());
factory.setMissingQueuesFatal(false);
return factory;
}
#Bean
public AmqpAdmin amqpAdmin() {
ConnectionFactory connectionFactory = connectionFactory().rabbitConnectionFactory();
debug("amqpAdmin");
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
rabbitAdmin.initialize();
//This is what puts HA policy on the queue it seems
Properties queueProperties = rabbitAdmin.getQueueProperties(MAIN_QUEUE_NAME);
log.debug("queueProperties {}", queueProperties);
return rabbitAdmin;
}
#PostConstruct
public void init() {
debug("postConstruct");
}
#Bean("pricingQueue")
#Primary
public Queue pricingQueue() {
return QueueBuilder.durable(MAIN_QUEUE_NAME)
.withArgument("x-dead-letter-exchange", "")
.withArgument("x-dead-letter-routing-key", DEAD_LETTER_QUEUE_NAME)
.withArgument("x-queue-master-locator", "min-masters")
.build();
}
#Bean
public Queue deadLetterQueue() {
return QueueBuilder.durable(DEAD_LETTER_QUEUE_NAME)
.withArgument("x-queue-master-locator", "min-masters")
.build();
}
#Bean
public DirectExchange exchange() {
return new DirectExchange(QUEUE_EXCHANGE_NAME);
}
#Bean
public Binding pricingBinding(#Qualifier("pricingQueue") Queue pricingQueue,
DirectExchange exchange) {
return BindingBuilder.bind(pricingQueue).to(exchange).with(MAIN_QUEUE_NAME);
}
#Bean
public DefaultMessageHandlerMethodFactory messageHandlerMethodFactory() {
DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();
factory.setMessageConverter(consumerJackson2MessageConverter());
return factory;
}
#Bean
public MappingJackson2MessageConverter consumerJackson2MessageConverter() {
return new MappingJackson2MessageConverter();
}
#Bean
public MessageConverter jsonMessageConverter() {
return new Jackson2JsonMessageConverter();
}
}
Related
I have the following bean definition.
#Bean
public DataSource hikariDataSource() {
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setJdbcUrl(JDBC_URL);
hikariConfig.setUsername(USERNAME);
hikariConfig.setPassword(PASSWORD);
return new HikariDataSource(hikariConfig);
}
When I get application context.
ApplicationContext ctx = new AnnotationConfigApplicationContext("org.example");
An exception is being thrown
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hikariDataSource' defined in org.example.config.Configuration: Failed to instantiate [javax.sql.DataSource]: Factory method 'hikariDataSource' threw exception with message: null
Is there any idea what can be the reason?
Maybe some of the answers from this thread will help.
https://stackoverflow.com/a/33213802/3816621
Also please check if you get #Configuration annotation on class level.
I have a spring batch written using Spring boot. My batch only reads from MongoDB and prints the record.
I'm not using any SQL DB nor have any dependencies declared in project but While running it I'm getting below exception:
s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'batchConfigurer' defined in class path resource [org/springframework/boot/autoconfigure/batch/BatchConfigurerConfiguration$JdbcBatchConfiguration.class]: Unsatisfied dependency expressed through method 'batchConfigurer' parameter 1; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.sql.DataSource' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2018-06-01 10:43:39.485 ERROR 15104 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 1 of method batchConfigurer in org.springframework.boot.autoconfigure.batch.BatchConfigurerConfiguration$JdbcBatchConfiguration required a bean of type 'javax.sql.DataSource' that could not be found.
- Bean method 'dataSource' not loaded because #ConditionalOnProperty (spring.datasource.jndi-name) did not find property 'jndi-name'
- Bean method 'dataSource' not loaded because #ConditionalOnClass did not find required class 'javax.transaction.TransactionManager'
Action:
Consider revisiting the conditions above or defining a bean of type 'javax.sql.DataSource' in your configuration.
In my pom.xml I've added below dependancies:
spring-boot-starter-batch
spring-boot-starter-data-mongodb
spring-boot-starter-test
spring-batch-test
Here's my batch configuration class:
#Configuration
#EnableBatchProcessing
public class BatchConfig {
#Autowired
private JobBuilderFactory jobBuilderFactory;
#Autowired
private StepBuilderFactory stepBuilderFactory;
#Autowired
private MongoTemplate mongoTemplate;
#Bean
public Job job() throws Exception {
return jobBuilderFactory.get("job1").flow(step1()).end().build();
}
#Bean
public Step step1() throws Exception {
return stepBuilderFactory.get("step1").<BasicDBObject, BasicDBObject>chunk(10).reader(reader())
.writer(writer()).build();
}
#Bean
public ItemReader<BasicDBObject> reader() {
MongoItemReader<BasicDBObject> reader = new MongoItemReader<BasicDBObject>();
reader.setTemplate(mongoTemplate);
reader.setCollection("test");
reader.setQuery("{'status':1}");
reader.setSort(new HashMap<String, Sort.Direction>() {
{
put("_id", Direction.ASC);
}
});
reader.setTargetType((Class<? extends BasicDBObject>) BasicDBObject.class);
return reader;
}
public ItemWriter<BasicDBObject> writer() {
MongoItemWriter<BasicDBObject> writer = new MongoItemWriter<BasicDBObject>();
return writer;
}
}
Here's is my launcher class:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
#SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class MyBatchApplication {
...
}
Spring Batch requires the use of a relational data store for the job repository. Spring Boot enforces that fact. In order to fix this, you'll need to add an in memory database or create your own BatchConfigurer that uses the Map based repository. For the record, the recommended approach is to add an in memory database (HSQLDB/H2/etc).
Here is my case:
I have two databases: one sybase and one mssql. I wish to access both of the database in a single service class. For example, I want to get some data from sybase, then I need do some update on mssql.
I have setup two datasources based on multiple samples found online, but Im unable to access my second database (sybase).
Here is my code:
pom.xml
spring.mvc.view.prefix: /WEB-INF/jsp/
spring.mvc.view.suffix: .jsp
# Database
# spring.datasource.jndi-name=jdbc/database1
spring.datasource.driver-class-name=net.sourceforge.jtds.jdbc.Driver
spring.datasource.url=jdbc:jtds:sqlserver://database1/db_aes
spring.datasource.username=user1
spring.datasource.password=password1
# Keep the connection alive if idle for a long time (needed in production)
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1
# 2nd Database
spring.secondDatasource.driver-class-name=net.sourceforge.jtds.jdbc.Driver
spring.secondDatasource.url=jdbc:jtds:sybase://database2/aidcconfig
spring.secondDatasource.username=user2
spring.secondDatasource.password=password2
spring.secondDatasource.hibernate.dialect = org.hibernate.dialect.SybaseASE15Dialect
spring.secondDatasource.testWhileIdle = true
spring.secondDatasource.validationQuery = SELECT 1
# Show or not log for each sql query
spring.jpa.show-sql = false
# Hibernate ddl auto (create, create-drop, update, validate)
spring.jpa.hibernate.ddl-auto = validate
# Naming strategy
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.EJB3NamingStrategy
# Use spring.jpa.properties.* for Hibernate native properties (the prefix is
# stripped before adding them to the entity manager)
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.SQLServerDialect
com.ibm.websphere.persistence.ApplicationsExcludedFromJpaProcessing=*
fileUploadServiceImpl
#Component("fileUploadService")
#Transactional
public class FileUploadServiceImpl implements FileUploadService {
#Autowired
#Qualifier("dbAesJdbcTemplate")
JdbcTemplate dbAesJdbcTemplate;
#Autowired
#Qualifier("aidcconfigJdbcTemplate")
JdbcTemplate aidcconfigJdbcTemplate;
private int uploadId = 1;
private void testDB(){
String db = aidcconfigJdbcTemplate.queryForObject("select db_name()", String.class);
System.out.println("database name: " + db);
}
...
}
DbAesDataSource
package config.database;
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(
entityManagerFactoryRef = "dbAesEntityManagerFactory",
transactionManagerRef = "dbAesTransactionManager",
basePackages = {"web.fileUpload.repo.db_aes.dao"}
)
public class DbAesDataSource {
#Primary
#Bean(name="dbAesDataSource")
#ConfigurationProperties(prefix = "spring.datasource")
public DataSource dbAesDataSource(){
return DataSourceBuilder.create().build();
}
#Bean(name="dbAesJdbcTemplate")
public JdbcTemplate dbAesJdbcTemplate(#Qualifier("dbAesDataSource") DataSource dbAesDataSource)
{
return new JdbcTemplate(dbAesDataSource);
}
#Bean(name="dbAesEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean dbAesEntityManagerFactory(
EntityManagerFactoryBuilder builder,
#Qualifier("dbAesDataSource") DataSource dbAesDataSource) {
return builder
.dataSource(dbAesDataSource)
.packages("web.fileUpload.repo.db_aes.models")
.build();
}
#Bean(name = "dbAesTransactionManager")
public PlatformTransactionManager dbAesTransactionManager(
#Qualifier("dbAesEntityManagerFactory") EntityManagerFactory dbAesEntityManagerFactory) {
return new JpaTransactionManager(dbAesEntityManagerFactory);
}
}
AidcconfigDataSource
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(
entityManagerFactoryRef = "aidcconfigEntityManagerFactory",
transactionManagerRef = "aidcconfigTransactionManager",
basePackages = {"web.fileUpload.repo.aidcconfig.dao"}
)
public class AidcconfigDataSource {
#Bean(name="aidcconfigDataSource")
#ConfigurationProperties(prefix = "spring.secondDatasource")
public DataSource aidcconfigDataSource(){
return DataSourceBuilder.create().build();
}
#Bean(name="aidcconfigJdbcTemplate")
public JdbcTemplate aidcconfigJdbcTemplate(#Qualifier("aidcconfigDataSource") DataSource aidcconfigDataSource)
{
return new JdbcTemplate(aidcconfigDataSource);
}
#Bean(name="aidcconfigEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean aidcconfigEntityManagerFactory(
EntityManagerFactoryBuilder builder,
#Qualifier("aidcconfigDataSource") DataSource aidcconfigDataSource) {
return builder
.dataSource(aidcconfigDataSource)
.packages("web.fileUpload.repo.aidcconfig.models")
.build();
}
#Bean(name = "aidcconfigTransactionManager")
public PlatformTransactionManager aidcconfigTransactionManager(
#Qualifier("aidcconfigEntityManagerFactory") EntityManagerFactory aidcconfigEntityManagerFactory) {
return new JpaTransactionManager(aidcconfigEntityManagerFactory);
}
}
Here is my error:
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.3.5.RELEASE:run (default-cli) on
project testUpload: An exception occurred while running. null: InvocationTargetException: Error creating bean with
name 'fileDownloadController': Injection of autowired dependencies failed; nested exception is org.springframework
.beans.factory.BeanCreationException: Could not autowire field: private web.fileUpload.services.FileUploadService w
eb.fileUpload.controller.FileDownloadController.fileUploadService; nested exception is org.springframework.beans.fa
ctory.BeanCreationException: Error creating bean with name 'fileUploadService': Injection of autowired dependencies
failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org
.springframework.jdbc.core.JdbcTemplate web.fileUpload.services.FileUploadServiceImpl.dbAesJdbcTemplate; nested exc
eption is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springfr
amework.jdbc.core.JdbcTemplate] found for dependency: expected at least 1 bean which qualifies as autowire candidat
e for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=tr
ue), #org.springframework.beans.factory.annotation.Qualifier(value=dbAesJdbcTemplate)} -> [Help 1]
If I removed the Qualifier in the FileUploadServiceImpl, then any jdbcTemplate will only connect to my Primary database which is db_aes. How can I access to my second datasource using jdbcTemplate?
Following are some of the references I used:
Spring Boot, Spring Data JPA with multiple DataSources
https://www.infoq.com/articles/Multiple-Databases-with-Spring-Boot
Multiple DataSource and JdbcTemplate in Spring Boot (> 1.1.0)
Trial#1
I noticed that it is unable to create the bean, and I placed some logger in the AidcconfigDataSource class. As a result, I didn't see my method is being executed. Thus, I assumed that the application is not reading my AidcconfigDataSource class.
I relocated the config folder as such, from java/config to java/web/config:
now I have another error:
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.3.5.RELEASE:run (default-cli) on
project testUpload: An exception occurred while running. null: InvocationTargetException: Error creating bean with
name 'dataSourceInitializerPostProcessor': Injection of autowired dependencies failed; nested exception is org.spr
ingframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.beans.facto
ry.BeanFactory org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerPostProcessor.beanFactory; nested e
xception is org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'aidc
configDataSource' defined in class path resource [web/config/database/AidcconfigDataSource.class]: factory-bean ref
erence points back to the same bean definition -> [Help 1]
Trial#2
I have changed my bean name from aidcconfigDataSource to aidcconfigDS and same to the primary datasource. Plus I have added "spring.jpa.open_in_view = false" in my application.properties. However another error happens. How to do this the right way?
2016-11-03 09:28:16.118 ERROR 11412 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.servic
e() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exce
ption is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springf
ramework.transaction.PlatformTransactionManager] is defined: expected single matching bean but found 2: dbAesTransa
ctionManager,aidcconfigTransactionManager] with root cause
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.
transaction.PlatformTransactionManager] is defined: expected single matching bean but found 2: dbAesTransactionMana
ger,aidcconfigTransactionManager
I think Spring Boot is trying to instantiate 2 beans with the same name:
aidcconfigDataSource.
One is your configuration class AidcconfigDataSource.class and the other one is the bean:
#Bean(name="aidcconfigDataSource")
#ConfigurationProperties(prefix = "spring.secondDatasource")
public DataSource aidcconfigDataSource(){
return DataSourceBuilder.create().build();
}
I have a repository of username/passwords which I am trying to configure into spring web security using a customUserDetailsService. My base package is called 'showcase'.
I have a WebSecurityConfiguration as:
#Configuration
#EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private DataSource datasource;
#Autowired
private CustomUserDetailsService customUserDetailsService;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(datasource)
.and()
.userDetailsService(customUserDetailsService);
// #formatter:on
}
I am trying to configure this datasource as follows:
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(basePackages = {
"showcase"
})
public class DatabaseConfig {
//#Resource
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
private static final String PROPERTY_NAME_HIBERNATE_FORMAT_SQL = "hibernate.format_sql";
private static final String PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";
private static final String PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY = "hibernate.ejb.naming_strategy";
private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
#Bean
public DataSource dataSource(Environment env) {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("java.sql.DriverManager");
dataSource.setUrl("jdbc:mysql://localhost:3306/mutibodb");
dataSource.setUsername("db");
dataSource.setPassword("");
return dataSource;
}
#Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, Environment env) {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource);
entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
entityManagerFactoryBean.setPackagesToScan("showcase");
Properties jpaProperties = new Properties();
jpaProperties.put(PROPERTY_NAME_HIBERNATE_DIALECT,"showcase.MySQLDialect");
jpaProperties.put(PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO,"create-drop");
jpaProperties.put(PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY,"org.hibernate.cfg.ImprovedNamingStrategy");
jpaProperties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL,false);
jpaProperties.put(PROPERTY_NAME_HIBERNATE_FORMAT_SQL,true);
entityManagerFactoryBean.setJpaProperties(jpaProperties);
return entityManagerFactoryBean;
}
#Bean
public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
}
The SQLDialect configuration is as follows:
public class MySQLDialect extends MySQL5InnoDBDialect {
#Override
public String getDropSequenceString(String sequenceName) {
return "drop sequence if exists " + sequenceName;
}
#Override
public boolean dropConstraints() {
return false;
}
I get an error which primarily says that: Unable to build Hibernate SessionFactory.
I am new to Spring and must be missing something. I am not using any xml based config and wish to stick to only java config. I can share details of the rest of my code if required.
Update:
Here is my CustomUserDetailsService:
#Service("userDetailsService")
public class CustomUserDetailsService implements UserDetailsService {
#Autowired
AppUserRepository repository;
#Autowired
private UserService userService;
private static final Logger logger = LoggerFactory.getLogger(CustomUserDetailsService.class);
#Override
public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {
logger.info("username:"+name);
AppUser u = repository.findByUserName(name);
if (u == null)
throw new UsernameNotFoundException("User details not found with this username: " + name);
String username = u.getUsername();
String password = u.getPassword();
List authList = new ArrayList();
authList.add(new SimpleGrantedAuthority("USER"));
User user = new User(username, password, authList);
return user;
}
The UserService mentioned above saves a user in the AppUserRepository. The AppUser is an entity.
The entire error is:
2014-12-28 12:02:59.555 INFO 5220 --- [ost-startStop-1] org.hibernate.Version : HHH000412: Hibernate Core {4.3.1.Final}
2014-12-28 12:02:59.557 INFO 5220 --- [ost-startStop-1] org.hibernate.cfg.Environment : HHH000206: hibernate.properties not found
2014-12-28 12:02:59.560 INFO 5220 --- [ost-startStop-1] org.hibernate.cfg.Environment : HHH000021: Bytecode provider name : javassist
2014-12-28 12:02:59.722 INFO 5220 --- [ost-startStop-1] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {4.0.4.Final}
2014-12-28 12:02:59.753 WARN 5220 --- [ost-startStop-1] o.h.e.jdbc.internal.JdbcServicesImpl : HHH000342: Could not obtain connection to query metadata : No suitable driver found for jdbc:mysql://localhost:3306/mutibodb
2014-12-28 12:02:59.760 INFO 5220 --- [ost-startStop-1] org.hibernate.dialect.Dialect : HHH000400: Using dialect: showcase.MySQLDialect
2014-12-28 12:02:59.767 INFO 5220 --- [ost-startStop-1] o.h.e.jdbc.internal.LobCreatorBuilder : HHH000422: Disabling contextual LOB creation as connection was null
2014-12-28 12:02:59.835 ERROR 5220 --- [cat-startStop-1] org.apache.catalina.core.ContainerBase : A child container failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].StandardContext[]]
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1123)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:799)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].StandardContext[]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
... 6 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.setFilterChainProxySecurityConfigurer(org.springframework.security.config.annotation.ObjectPostProcessor,java.util.List) throws java.lang.Exception; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'webSecurityConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private showcase.CustomUserDetailsService showcase.WebSecurityConfiguration.customUserDetailsService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDetailsService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: showcase.AppUserRepository showcase.CustomUserDetailsService.repository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'appUserRepository': Cannot create inner bean '(inner bean)#165fa72a' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property 'entityManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#165fa72a': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [showcase/DatabaseConfig.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
I had not focused on the hibernate errors before. I guess my hibernate config is wrong. But is there a way of doing this without injecting the datasource? When I did not have the datasource field in the securrity config and was only using auth.userDetailsService(customUserDetailsService), I was getting a No qualifying bean of type [javax.sql.DataSource] is defined error. Trying to fix that lead me to this path.
I have a class of GenerateKey which is for spring mvc boot. Since it needs to contact database and message queue, so I tried to wire it using xml
#RestController
public class GenerateKey {
final private DriverManagerDataSource dataSource;
final private AmqpTemplate rabbitMQTemplate;
final private String queueName;
public GenerateKey(DriverManagerDataSource dataSource,AmqpTemplate rabbitMQTemplate,String queueName){
this.dataSource=dataSource;
this.rabbitMQTemplate =rabbitMQTemplate;
this.queueName =queueName;
}
#RequestMapping("/key/generate")
public String generateKey(#RequestParam(value = "businesskey") String businesskey, #RequestParam(value = "customer") String customer, Model model) {
JdbcTemplate jdbctemplate = new JdbcTemplate(dataSource);
JSONObject obj = new JSONObject();
obj.put("businesskey", businesskey);
obj.put("customer", customer);
rabbitMQTemplate.convertAndSend(queueName, obj.toString());
System.out.println(businesskey+customer);
return "greeting" + businesskey + customer;
}
}
the xml configurations is as the following and using
#ImportResource( { "rabbit-listener-context.xml" } )
to import it
<bean id="request" class="com.testcom.keyservice.GenerateKey" c:dataSource-ref="dataSource" c:rabbitMQTemplate-ref="keyRequestTemplate" c:queueName="${keyRequestQueueName}"/>
but it complain "No default constructor found" as following:
2014-11-26 21:42:16.095 INFO 17400 --- [ main] utoConfigurationReportLoggingInitializer :
Error starting ApplicationContext. To display the auto-configuration report enabled debug logging (start with --debug)
2014-11-26 21:42:16.097 ERROR 17400 --- [ main] o.s.boot.SpringApplication : Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'generateKey' defined in file [/home/oracle/NetBeansProjects/rabbitmq-native/keyService/build/classes/main/com/testcom/keyservice/GenerateKey.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.testcom.keyservice.GenerateKey]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.testcom.keyservice.GenerateKey.<init>()
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1095)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1040)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:505)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:725)
Exception in thread "main" at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:762)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicatixt.java:482)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
Since you are using Spring Boot I assume you have also #ComponentScan active in your application. Because of that you create two instances of GenerateKey class - once because of #RestController annotation, second time in XML. I believe that's not what you want to achieve.
Get rid of XML declaration of request bean representing GeneratorKey class and use only Java based autowiring.
#RestController
public class GenerateKey {
private final DriverManagerDataSource dataSource;
private final AmqpTemplate rabbitMQTemplate;
private final String queueName;
#Autowired
public GenerateKey(#Qualifier("dataSource") DriverManagerDataSource dataSource, #Qualifier("keyRequestTemplate") AmqpTemplate rabbitMQTemplate, #Value("${keyRequestQueueName}") String queueName) {
this.dataSource=dataSource;
this.rabbitMQTemplate =rabbitMQTemplate;
this.queueName =queueName;
}