Encountered error "Consider defining a bean of type 'java.util.concurrent.atomic.AtomicReference' in your configuration" - spring-boot

I am getting the below error while starting spring boot application.
The injection point has the following annotations:
#org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type
'java.util.concurrent.atomic.AtomicReference' in your configuration.
Below is the code .
package de.summer.sampleapplayerv1;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#SpringBootApplication(scanBasePackages = {"de.summer.sampleapplayerv1"})
#EnableConfigurationProperties
#EnableJpaRepositories (basePackages ="de.summer.sampleapplayerv1.repository")
#EnableTransactionManagement
public class Sampleapplayerv1Application {
public static void main(String[] args) {
SpringApplication.run(Sampleapplayerv1Application.class, args);
}
}
package de.summer.sampleapplayerv1.service;
import de.summer.sampleapplayerv1.domain.QueueAndPublish;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
#Slf4j
#Service
public class QueueAndPublishServiceImpl implements QueueAndPublishService{
private final AtomicReference<List<QueueAndPublish>> currentJob;
public QueueAndPublishServiceImpl(
#Qualifier("currentJob") AtomicReference<List<QueueAndPublish>> currentJob
){
this.currentJob=currentJob;
}
#Override
public QueueAndPublish getJobStatus(UUID jobId) {
return (QueueAndPublish) currentJob.get().stream()
.filter(j -> j.getJobId()==jobId)
.collect(Collectors.toList());
}
#Override
public List<QueueAndPublish> getAllJobStatus() {
return currentJob.get();
}
#Override
public QueueAndPublish getCategoryDataProcess() {
List<QueueAndPublish> processList=new ArrayList<QueueAndPublish>();
QueueAndPublish process=QueueAndPublish.builder()
.jobId(UUID.randomUUID())
.jobName("Name for Job")
.jobStatus("Not Yet Started")
.build();
Thread t1=new Thread(process.getJobId().toString()){
#Override
public void run(){
log.info("How are you doing");
process.setJobStatus("Completed");
}
};
t1.start();
processList.add(process);
currentJob.set(processList);
return process;
}
#Override
public QueueAndPublish getCatgeoryDataProcessStatus() {
return null;
}
}
package de.summer.sampleapplayerv1.domain;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.Id;
import java.io.Serializable;
import java.util.UUID;
#Getter
#Setter
#Builder
#Entity
public class QueueAndPublish implements Serializable {
#Id
private UUID jobId;
private String jobName;
private String jobStatus;
}
If I remove the constructor, spring boot application is starting up without any errors. If included , start up is failing with unsatisfied dependency errors.
Can someone please help on what is wrong with config?

You expect Spring to create an instance of class QueueAndPublishServiceImpl for the implementation of QueueAndPublishService. This instance needs a constructor parameter of type AtomicReference<List<QueueAndPublish>> injected.
But you obviously do not define any Spring bean (Bean, Component, Service, ...) of that type.
Edit:
public QueueAndPublishServiceImpl(
#Qualifier("currentJob") AtomicReference<List<QueueAndPublish>> currentJob
){
this.currentJob=currentJob;
}
Here you define a constructor parameter to have a AtomicReference<List<QueueAndPublish>>, and even specify it with a #Qualifier. So you need to provide a Spring bean of this class with this qualifier, otherwise Spring cannot inject it into the constructor call.

Consider defining a bean of type 'java.util.concurrent.atomic.AtomicReference' in your configuration.
Means "something like" adding this to your Sampleapplayerv1Application:
#Bean("currentJob") AtomicReference<List<QueueAndPublish>> currentJob() {
// or a list implementation of your choice.
return new AtomicReference<>(new java.util.ArrayList<>());
}

Related

I am trying to get NoUniqueBeanDefinitionException but i am not getting it any clue why i am not getting

I am trying to get NoUniqueBeanDefinitionException but i am not getting it any clue why i am not getting
package com.example.demo;
public interface IDateGen {
}
package com.example.demo;
import org.springframework.stereotype.Service;
#Service
public class DateGen implements IDateGen {
}
package com.example.demo;
import org.springframework.stereotype.Service;
#Service
public class DateGen2 implements IDateGen {
}
package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
#Component
public class DateGenUtil {
#Autowired
private IDateGen dateGen;
public IDateGen getDateGen() {
return dateGen;
}
public void setDateGen(IDateGen dateGen) {
this.dateGen = dateGen;
}
}
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
#SpringBootApplication
public class Demo3Application {
public static void main(String[] args) {
ApplicationContext appContext = SpringApplication.run(Demo3Application.class, args);
DateGenUtil util = appContext.getBean(DateGenUtil.class);
System.out.println(util.getDateGen());
}
}
When i run the main method i getting
com.example.demo.DateGen#6075b2d3
Can anyone tell why i am not getting NoUniqueBeanDefinitionException ? Thanks in advance
The dependency injection first checks for autoWiring by type and then autowire by name, wen it looks for dateGen dependency in class DateGenUtil it checks by type then it is getting two Objects, then again it tries to do autoWiringByName it gets the one object
if we rename the variable like in the below code it gives the exception, hope anyone can confirm this
#Component
public class DateGenUtil {
#Autowired
//private IDateGen dateGen;
private IDateGen date;
}

Spring Boot did not Autowiring

Can someone tell me please what I'm doing wrong, I'm trying to develop a little application but I just simply can't Autowire a class in the controller, I have been researching and I Know that for Autowire works, my class must be in a child package of my #SpringBootApplication annotation, or I should specify in #ComponentScan annotation the package of my class, but no matters what I do I still getting the same error:
This is my project structure:
package net.spring.auditoria;
import org.springframework.boot.SpringApplication;T
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class AuditoriaApplication {
public static void main(String[] args) {
SpringApplication.run(AuditoriaApplication.class, args);
}
}
Controller:
package net.spring.auditoria.bll;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
#Controller
public class AuditoriaController {
#Autowired
private AuditoriaManagement am;
private final Logger LOGGER = LoggerFactory.getLogger(AuditoriaController.class);
#GetMapping("/auditar")
public String auditar() {
LOGGER.info("auditar()");
return "main";
}
}
https://github.com/jlpm-mex/auditoria
Because AuditoriaManagement is not a Spring bean or component.

How to create same Bean using Constructor Injection in Spring boot for different property values

I have to create multiple beans of same type for different property value which is to be injected using constructor.
Currently I have used Bean scope as Prototype & created multiple methods to read different properties to create new object. How to combine all the different methods into single method and to supply different values at run time to create new bean.
package com.demo.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
#Configuration
public class ConfigClass {
#Bean(name="RC")
public JavaClient getClient(#Autowired Environment env)
{
String sName=env.getProperty("RCSName");
String aUrl=env.getProperty("RCAUrl");
String dUrl=env.getProperty("RCDUrl");
return new JavaClient(sName,aUrl,dUrl);
}
#Bean(name="O")
public JavaClient getOClient(#Autowired Environment env)
{
String sName=env.getProperty("OSName");
String aUrl=env.getProperty("OAUrl");
String dUrl=env.getProperty("ODUrl");
return new JavaClient(sName,aUrl,dUrl);
}
}
Now it is creating 2 beans as per above code. Expectation: How to combine getClient & getOClient into single method, but the property to be supplied in a loop to create multiple beans of same type JavaClient
I have modified my ConfigClass as below & created ApplicationContextAware to inject beans by reading file properties.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.scheduling.annotation.EnableScheduling;
#Configuration
#EnableScheduling
public class ConfigClass {
#Bean
#Scope("prototype")
public JavaClient getClient(String sName,String aUrl,String dUrl)
{
return new JavaClient(sName,aUrl,dUrl);
}
}
Then Have created ApplicationContextAware to create Beans.
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Iterator;
import java.util.List;
import javax.annotation.PostConstruct;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
#Component
public class ApplicationContextProvider implements ApplicationContextAware {
private ApplicationContext applicationContext;
#Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public ApplicationContext getContext() {
return applicationContext;
}
#PostConstruct
public void init()
{
try {
String fileName = "Url.txt";
Resource resource = new ClassPathResource(fileName);
File file = resource.getFile();
List<String> lines = Files.readAllLines(file.toPath());
for (Iterator<String> iterator = lines.iterator(); iterator.hasNext();) {
String line = (String) iterator.next();
String[] s = line.split(",");
applicationContext.getBean(JavaClient.class,s[0], s[1], s[2]);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

No instance(s) of type variable(s) T exist so that Flux<T> confirms to Mono<? extend R)

I am implementing Spring webflux demo application and have written my demo application as like that
package com.abcplusd.application;
import com.abcplusd.domain.Event;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import java.util.Collections;
import java.util.Date;
import java.util.stream.Stream;
#SpringBootApplication
public class ReactiveClientApplication {
#Bean WebClient webClient() {
return WebClient.create("http://localhost:8080");
}
#Bean CommandLineRunner demo(WebClient webClient) {
return args -> {
webClient.get()
.uri("/events")
.accept(MediaType.TEXT_EVENT_STREAM)
.exchange()
.flatMap(clientResponse -> clientResponse.bodyToFlux(Event.class))
.subscribe(System.out::println);
};
}
public static void main(String[] args) {
new SpringApplicationBuilder(ReactiveClientApplication.class)
.properties(Collections.singletonMap("server.port", "8081"))
.run(args);
}
}
It shows the following error
Error:(29, 41) java: incompatible types: no instance(s) of type variable(s) T exist so that reactor.core.publisher.Flux<T> conforms to reactor.core.publisher.Mono<? extends R>
The above error is at this line:
.flatMap(clientResponse -> clientResponse.bodyToFlux(Event.class)))
Event Class
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Date;
#Data
#AllArgsConstructor
public class Event {
private long id;
private Date when;
}
Can anybody help me to solve the error?
It works me after i have done these changes in my code
.flatMap(clientResponse -> clientResponse.bodyToFlux(Event.class)))
to
.flatMapMany(clientResponse -> clientResponse.bodyToFlux(Event.class))
and
#NoArgsConstructor annotation in Event.Class
as follows:
import java.util.Date;
#Data
#AllArgsConstructor
#NoArgsConstructor
public class Event {
private long id;
private Date when;
}
flatMapMany instead of flatMap works.
However when you add property spring.main.web_environment=false to application.properties file, webClient simply doesn't work.

Spring cloud #HystrixCommand doesn't proxy the method which is invoked in CompletableFuture.supplyAsync

I have one spring component bean which contains a method methodA defined by #HystrixCommand with fallbackMethod. The bean has another method methodB invokes methodA by CompletableFuture.supplyAsync(...). I expect Hystrix javanica will weave the aspect on methodA, but when I debug it, I didn't see hystrix aspect is weaved.
Here are some of the main sudo code,
TestApplication:
package com.my.own.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication(scanBasePackages = "com.my.own.test")
public class TestApplication {
public static void main(final String[] args) throws Exception {
SpringApplication.run(TestApplication.class, args);
}
}
ApplicationConfiguration:
package com.my.own.test;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
#Configuration
#EnableAspectJAutoProxy(exposeProxy = true)
#EnableConfigurationProperties
#EnableCircuitBreaker
public class ApplicationConfig {
}
AsyncConfig:
package com.my.own.test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
#Configuration
#EnableAsync
public class AsyncConfig {
#Value("${spring.threadpool.executor.core:10}")
private int corePoolSize;
#Value("${spring.threadpool.executor.max:20}")
private int maxPoolSize;
#Value("${spring.threadpool.executor.queue:1000}")
private int queueCapacity;
#Value("${spring.threadpool.executor.timeout:true}")
private boolean coreThreadTimeOut;
#Value("${spring.threadpool.executor.keepalive:30000}")
private int keepAlive;
#Value("${spring.threadpool.executor.prefix:ThreadPoolTaskExecutor}")
private String threadNamePrefix;
#Bean("taskExecutor")
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setAllowCoreThreadTimeOut(coreThreadTimeOut);
executor.setKeepAliveSeconds(keepAlive);
executor.setThreadNamePrefix(threadNamePrefix + "-");
executor.initialize();
return executor;
}
}
TestController:
package com.my.own.test.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.my.own.test.core.TestProcessor;
#RestController
public class TestController {
private static Logger logger = LoggerFactory.getLogger(TestController.class);
#Autowired
TestProcessor tester;
#RequestMapping(value = "/test", method = { RequestMethod.POST })
public void test() {
tester.methodB();
}
}
TestProcessor:
package com.my.own.test.core;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
#Component
public class TestProcessor {
#Autowired
private ThreadPoolTaskExecutor executor;
public void methodB() {
final List<CompletableFuture<String>> a = new ArrayList<>();
a.add(CompletableFuture.supplyAsync(() -> methodA(), executor));
CompletableFuture.allOf(a.toArray(new CompletableFuture[a.size()])).join();
}
#HystrixCommand(fallbackMethod = "deferPushdown")
public String methodA() {
if (true) {
throw new RuntimeException();
} else {
return "methodA";
}
}
public String deferMethodA() {
return "deferMethodA";
}
}
Run output
Jan 03, 2018 2:55:55 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.util.concurrent.CompletionException: java.lang.RuntimeException] with root cause
java.lang.RuntimeException
at com.my.own.test.core.TestProcessor.methodA(TestProcessor.java:40)
at com.my.own.test.core.TestProcessor.lambda$0(TestProcessor.java:33)
at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1590)
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)
P.S.
From the output, methodA is not invoked from hystrix aspect, but by lambda directly. Is this an issue on Hystrix or javanica? Please share if you know a solution. I appreciate it.
Unless you’re using aspectj weaving (which requires special handling of compile steps, I think), spring defaults to using interface/cglib weaving, which only applies to the first method called from outside the class, as described in https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#aop-understanding-aop-proxies.
In summary, if you call methodB, no aspect applies and the call from methodB to methodA is not eligible for aspect interception.
To activate the aspect you have to call methodB directly from outside the TestProcessor class.

Resources