Cannot create spring beans - spring

I have spring application and have defined the Clock bean in my SpringMvcConfig.java as follows
#Bean
public Clock clock() {
return Clock.systemDefaultZone();
}
I am using it in my service
#Service
#RequiredArgsConstructor
#Slf4j
public class DeliveryEstimationService {
#NonNull
private final SalesChannelService salesChannelService;
#NonNull
private final MessageSource messageSource;
#NonNull
private final Clock clock;
public List<LocalDateTime> applyCutoffHoursToLocalDate(List<Integer> cutoffWindowHourList, int plusDays) {
return cutoffWindowHourList.stream().map(cutoffWindowHour -> LocalDateTime.of(
LocalDate.now(clock), LocalTime.of(cutoffWindowHour, 0)).plusDays(plusDays))
.collect(Collectors.toList());
}}
And I see this error
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640)
... 83 more
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'deliveryEstimationService' defined in file [/home/runner/work/checkout-service/checkout-service/target/classes/com/checkout/delivery/DeliveryEstimationService.class]: Unsatisfied dependency expressed through constructor parameter 2; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.time.Clock' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:798)
Can someone tell me why spring app cannot create the bean?
I had to use clock because I need to set fixed time for testing purpose
void getFixedClock(LocalDate date) {
fixedClock = Clock.fixed(date.atStartOfDay(ZoneId.systemDefault()).toInstant(), ZoneId.systemDefault());
doReturn(fixedClock.instant()).when(clock).instant();
doReturn(fixedClock.getZone()).when(clock).getZone();
}

Related

#DataJpaTest loads KafkaConfiguration and fails test

#DataJpaTest
class DataJpaVerificationTest {
#Autowired
private JdbcTemplate template;
#Test
public void testTemplate() {
assertThat(template).isNotNull();
}
}
When I run this test I get the following error:
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'kafkaConfig' defined in file
[***\config\KafkaConfig.class]:
Unsatisfied dependency expressed through constructor parameter 0;
nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type
'org.springframework.boot.autoconfigure.kafka.KafkaProperties'
available: expected at least 1 bean which qualifies as autowire
candidate. Dependency annotations: {}
where KafkaConfig class is a part of my application (app read data from Kafka and saves data to DB) and looks like:
#Configuration
#RequiredArgsConstructor
public class KafkaConfig {
private final KafkaProperties kafkaProperties;
#Bean
public Properties consumerProperties() {
Properties props = new Properties();
props.putAll(this.kafkaProperties.buildConsumerProperties());
return props;
}
}
Based on information that I googled about DataJpaTest annotation:
created application context will not contain the whole context needed
for our Spring Boot application, but instead only a “slice” of it
containing the components needed to initialize any JPA-related
components like our Spring Data repository.
So the question is: why Spring tries to load to the context Kafka specific bean for DataJpaTest?

UnsatisfiedDependencyException during test

I use psring boot 2, postgres and Jpa with hibernate.
I would like to test one of my class
#Component
public class ExportsFacade {
private SamplesService sampleService;
private SamplesRepository sampleRepository;
#Autowired
public ExportsFacade(SamplesService sampleService, SamplesRepository sampleRepository) {
this.sampleService = sampleService;
this.sampleRepository=sampleRepository;
}
...
}
I created this test
#RunWith(SpringRunner.class)
#DataJpaTest
#AutoConfigureTestDatabase(replace=Replace.NONE)
public class ExportsFacadeTest {
#Autowired
private ExportsFacade exportsFacade;
#Test
public void export() throws IOException {
exportsFacade.generateExport();
}
}
I get this error
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'com.lcm.facade.ExportsFacadeTest':
Unsatisfied dependency expressed through field 'exportsFacade'; nested
exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type 'com.lcm.facade.ExportsFacade' available:
expected at least 1 bean which qualifies as autowire candidate.
Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}

Spring Boot - Can't handle IllegalStateException

I am in the process of learning spring boot, however, I encountered a problem and I can not find a solution. When I try to run the test, I get the following exception.
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'bookServiceImplementation' defined in file []: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'uploadFileServiceImplementation' defined in file []: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.modelmapper.ModelMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'uploadFileServiceImplementation' defined in file []: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.modelmapper.ModelMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.modelmapper.ModelMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
I tried to put an annotation in different places, but it did not solve my problem. I completely don't know how should I create ModelMapper bean. Maybe you will know how to deal with it. Here is my code:
BookServiceImplementation.class
#Service
public class BookServiceImplementation implements BookService {
private BookRepository bookRepository;
private UploadFileService uploadFileService;
private ModelMapper modelMapper;
#Autowired
public BookServiceImplementation(BookRepository bookRepository, UploadFileService uploadFileService,
ModelMapper modelMapper){
this.bookRepository = bookRepository;
this.uploadFileService = uploadFileService;
this.modelMapper = modelMapper;
}
#Override
public void addBook(AddBookResource addBookResource) {
Book book = new Book();
Long coverImageId = addBookResource.getCoverImageId();
Long contentId = addBookResource.getContentId();
UploadFile coverImage = null;
UploadFile bookContent = null;
if (coverImage != null){
coverImage = uploadFileService.findById(coverImageId)
.map(fileResource -> modelMapper.map(fileResource, UploadFile.class))
.orElse(null);
}
if (contentId != null){
bookContent = uploadFileService.findById(contentId)
.map(fileResource -> modelMapper.map(fileResource, UploadFile.class))
.orElse(null);
}
book.setCoverImage(coverImage);
book.setContent(bookContent);
book.setTitle(addBookResource.getTitle());
book.setDescription(addBookResource.getDescription());
book.setCategories(Arrays.stream(addBookResource.getCategories())
.map(Category::new)
.collect(Collectors.toSet()));
bookRepository.save(book);
}
}
UploadFileServiceImplementation.class
#Service
public class UploadFileServiceImplementation implements UploadFileService {
private UploadFileRepository uploadFileRepository;
private ModelMapper modelMapper;
#Autowired
public UploadFileServiceImplementation(UploadFileRepository uploadFileRepository, ModelMapper modelMapper){
this.uploadFileRepository = uploadFileRepository;
this.modelMapper = modelMapper;
}
#Transactional
#Override
public Long save(String filename, byte[] data) {
UploadFile uploadFile = new UploadFile();
uploadFile.setFileName(filename);
uploadFile.setData(data);
UploadFile saved = uploadFileRepository.save(uploadFile);
return saved.getId();
}
#Override
public Optional<FileResource> findById(Long id) {
return uploadFileRepository.findById(id)
.map(file -> modelMapper.map(file, FileResource.class));
}
}
EDIT
After a suggested changes I still got an IllegalStateException:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'bookService': Unsatisfied dependency expressed through field 'uploadFileService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'uploadFileService': Unsatisfied dependency expressed through field 'modelMapper'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.modelmapper.ModelMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'uploadFileService': Unsatisfied dependency expressed through field 'modelMapper'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.modelmapper.ModelMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.modelmapper.ModelMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Step 1: Add a #Bean for Model mapper if already not there in main application class or configuration class:
#SpringBootApplication
public class Application {
public static void main(String[] args){
SpringApplication.run(Application.class, args);
}
#Bean
public ModelMapper modelMapper() {
return new ModelMapper();
}
}
Step 2: Here is how you can manage it, please make below chnages in service impl:
#Service("uploadFileService")
public class UploadFileServiceImplementation implements UploadFileService {
#Autowired
private UploadFileRepository uploadFileRepository;
#Autowired
private ModelMapper modelMapper;
//Remove constructure now.
same do for BookServiceImplementation
#Service("bookService")
public class BookServiceImplementation implements BookService {
#Autowired
private BookRepository bookRepository;
#Autowired
private UploadFileService uploadFileService;
#Autowired
private ModelMapper modelMapper;
//remove constructure

Autowiring not working in SpringBoot controller

Hi i was trying to work over an existing SpringBoot application. I created a service class and tried to autowire it in the existing controller, but when trying to build, its failing saying bean injection failed.
Cause: org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'controller': Injection of autowired
dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Could not
autowire field: private
com.disooza.www.card.dispenser.service.FilaPartnerService
com.disooza.www.card.dispenser.controller.CardDispenserController.FilaPartnerService;
nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type
[com.disooza.www.card.dispenser.service.FilaPartnerService] found for
dependency: expected at least 1 bean which qualifies as autowire
candidate for this dependency. Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}
at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
Following is my controller class:
#Controller
#RequestMapping(value = "/service")
public class CardController {
private static final Logger LOGGER = LoggerFactory.getLogger(CardController.class);
#Autowired
private CardDao dao;
#Autowired
private PaymentService paymentService;
#Autowired
private FilaPartnerService filaPartnerService;
FilaPartnerService is the newly created interface, and rest all autowires are working fine in this controller.
Interesting thing is when I try to place this service class in any other controller it is working fine. Any help over this issue will be appreciated, since I'm stuck with it.
This is my service interface:
#Service
public interface FilaPartnerService {
RetrievePaymentTokenResponse retrieveXXX(SupplierRequest request);
}
This is the implementation class:
#Component
public class FilaPartnerServiceImpl implements FilaPartnerService {
#Autowired
private RestTemplate restTemplate;
#Autowired
private RetrieveRequestBuilder retrieveRequestBuilder;
#Value("${filaPartner.url}")
private String filaServiceUrl;
#Override
public RetrievePaymentTokenResponse retrieveFilaPaymentToken(SupplierTokenRequest request) {
RetrievePaymentTokenResponse tokenResponse = null;
RetrievePaymentTokenRequest paymentServiceRequest = retrievePaymentTokenRequestBuilder.retrievePaymentTokenRequestBuilder(request);
try {
tokenResponse =
restTemplate.postForObject( FilaServiceUrl, paymentServiceRequest, RetrievePaymentTokenResponse.class);
} catch (RestClientException exp) {
//TO-DO return error code
}
return null;
}
}

How to create a Spring bean for apache logging Log class?

I'd like to create an autowired bean in a Dao class in order to do logging opperations. My way was hitherto static final statement like this:
private static final Log log = LogFactory.getLog(LoggedClass.class);
But now I'm trying to use IoC to turn classes decoupled.
If just add configuration in pom.xml and try to do sth like
#Autowired
Log log;
I receive an error message:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'funciDaoImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.apache.commons.logging.Log br.com.bb.dirco.dao.impl.FunciDaoImpl.log; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'log' defined in class path resource [com/company/project/util/PersistenceConfig.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [java.lang.Class]: : No qualifying bean of type [java.lang.Class] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.Class] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
In order to get a logger, I had to provide a class to getLog method on LogFactory class and attribute it to Log instance. There's a way to do it using #Autowired Spring IoC? Thanks!
You can inject only those objects which are managed/created by Spring container. You have to register your bean (or factory method creating the bean) with container (with annotations like #Component/#Singleton/... or directly in xml)
In your case it's not very applicable since you have to have many different types (for every class) of logger objects provided by Spring and then when you inject they would have to be identified by different name/type for every class.
P.S. I don't see any problem using it the way you use it now
Where I work we have implemented support for #Autowired SLF4J Loggers using Springs BeanPostProcessor.
First you need to define an Logger placeholder bean in your application context. This bean is going to be injected by Spring into all bean with a #Autowired Logger field.
#Configuration
public class LoggerConfig {
#Bean
public Logger placeHolderLogger() {
return PlaceHolder.LOGGER;
}
#Bean
public AutowiredLoggerBeanPostProcessor loggerPostProcessor() {
return new AutowiredLoggerBeanPostProcessor();
}
}
Then you an AutowiredLoggerBeanPostProcessor which inspects all beans, indetify bean that contain Logger fields annotated with #Autowired (at this point should contain a reference to the Logger placeholder bean), create a new Logger for the partilcar bean an assigned it to the fields.
#Component
public class AutowiredLoggerBeanPostProcessor implements BeanPostProcessor, PriorityOrdered {
#Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
attachLogger(bean);
return bean;
}
#Override
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
attachLogger(bean);
return bean;
}
private void attachLogger(final Object bean) {
ReflectionUtils.doWithFields(bean.getClass(), new FieldCallback() {
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
if (Logger.class.isAssignableFrom(field.getType()) &&
(field.isAnnotationPresent(Autowired.class) ||
field.isAnnotationPresent(Inject.class))) {
ReflectionUtils.makeAccessible(field);
if (field.get(bean) == PlaceHolder.LOGGER) {
field.set(bean, LoggerFactory.getLogger(bean.getClass()));
}
}
}
});
}
#Override
public int getOrder() {
return HIGHEST_PRECEDENCE;
}
}

Resources