Field ** in com.** required a bean of type 'com.**' that could not be found - spring

I'm following this tutorial and I'm having some trouble starting my application.
When I run mvn spring-boot:run in the backend folder I get the following error:
Field movieRepository in com.movieseat.services.impl.MovieServiceImpl required a bean of type 'com.movieseat.repositories.MovieRepository' that could not be found.
MovieServiceIml.java
package com.movieseat.services.impl;
// Java imports
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
// Spring imports
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
// Project imports
import com.movieseat.models.Movie;
import com.movieseat.services.MovieService;
import com.movieseat.repositories.MovieRepository;
#Service
public class MovieServiceImpl implements MovieService {
#Autowired private MovieRepository movieRepository;
#Override public List<Movie> getAllmovies() {
List<Movie> movies = new ArrayList<Movie>();
Iterator<Movie> iterator = movieRepository.findAll().iterator();
while (iterator.hasNext()) {
movies.add(iterator.next());
}
return movies;
}
}
MovieRepository.java
package com.movieseat.repositories;
// Java imports
import java.io.Serializable;
// Spring imports
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
// Project imports
import com.movieseat.models.Movie;
#Repository
public interface MovieRepository extends CrudRepository<Movie, Serializable> {}
The following structure is used:
com
movieseat
Application.java
controllers
MovieController.java
models
MovieModel.java
repositories
MovieRepository.java
services
impl
MovieServiceImpl.java
MovieService.java
And this is my Application.java:
package com.movieseat;
// Spring importss
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#SpringBootApplication
#ComponentScan({"com.movieseat.*"})
#EnableJpaRepositories("com.movieseat.repositories.*")
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
My thought is that using #EnableJpaRepositories("com.movieseat.repositories.*") would make all repositories accessible. But I'm doing something wrong.

Try it without * (wildcard),
#EnableJpaRepositories("com.movieseat.repositories")
Make sure you have the #Entity annotation on your Movie.

Related

Spring can't find repository bean

I'm using spring boot with spring data jdbc and I got trouble with run my app
I have StudentService class:
package ru.turnip.service;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import ru.turnip.model.Student;
import ru.turnip.repository.StudentRepository;
import ru.turnip.utils.student.BusyStudents;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
#Service
public class StudentService {
private final BusyStudents busyStudents;
private final StudentRepository studentRepository;
public StudentService(BusyStudents busyStudents, StudentRepository studentRepository) {
this.busyStudents = busyStudents;
this.studentRepository = studentRepository;
}
...
}
And StudentRepository interface:
package ru.turnip.repository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import ru.turnip.model.Student;
import java.util.UUID;
#Repository
public interface StudentRepository extends CrudRepository<Student, UUID> { }
So, when I try to run app, I get an eror, and I can't figure out where the problem is.
That my config class:
package ru.turnip;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.relational.core.mapping.event.BeforeSaveEvent;
import org.springframework.scheduling.annotation.EnableScheduling;
import ru.turnip.model.Student;
import java.time.Clock;
import java.util.UUID;
#ComponentScan
#Configuration
#EnableScheduling
public class ApplicationConfig {
#Bean
public Clock clock() {
return Clock.systemDefaultZone();
}
#Bean
public ApplicationListener<BeforeSaveEvent> idGenerator() {
return event -> {
var entity = event.getEntity();
if (entity instanceof Student) {
((Student) entity).setId(UUID.randomUUID());
}
};
}
}
And project structure:
I tried to explicitly set package to be scanned, and also moved the repository to the package with the config. Also I tried to annotate with #Autowired field and constructor in StudentService

#Scheduled works in Spring Boot application but not in #SpringBootTest

What is the reason that the #Scheduled function runs in Spring Boot Application but not in test environment (#SpringBootTest) ?
I am following the tutorial at https://github.com/spring-guides/gs-scheduling-tasks, the repository's test runs fine, but mine #Scheduled function does not run for once in my test, although it is working fine in my Spring Boot application.
Is it because of the version of Junit (The tutorial is using Junit5 while I am using JUnit 4) ?
My purpose of this test is to check the correctness of the configuration of my scheduler.
Below is the code I replicated with difference in Junit version.
BootApplication.java
package com.itsedo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
// SecurityAutoConfiguration: exclude default spring security boot file.
#SpringBootApplication(exclude = { SecurityAutoConfiguration.class })
#ComponentScan("com.itsedo")
#EnableScheduling
public class BootApplication extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(BootApplication.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(BootApplication.class, args);
}
}
ScheduledTasks.java
package com.itsedo.scheduler;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
#Component
public class ScheduledTasks {
private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class);
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
#Scheduled(fixedRate = 5000)
public void reportCurrentTime() {
log.info("The time is now {}", dateFormat.format(new Date()));
}
}
File ScheduledTasksTest.java
package com.itsedo.test;
import org.awaitility.Duration;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.context.junit4.SpringRunner;
import static org.awaitility.Awaitility.await;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.verify;
import com.itsedo.scheduler.ScheduledTasks;
#RunWith(SpringRunner.class)
#SpringBootTest
public class ScheduledTasksTest {
#SpyBean
ScheduledTasks tasks;
#Test
public void reportCurrentTime() {
await().atMost(Duration.TEN_SECONDS).untilAsserted(() -> {
verify(tasks, atLeast(2)).reportCurrentTime();
});
}
}
Test Output
Running Spring Boot application

org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class

In my microservice Spring Boot application i added Swagger for my REST api's documentation. Before that my Spring Boot microservice was started fine. But When I add my add my SwaggerConfig the project can't start. I had this error :
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [com.myproject.MyApplication]; nested exception is java.io.FileNotFoundException: class path resource [springfox/bean/validators/configuration/BeanValidatorPluginsConfiguration.class] cannot be opened because it does not exist
The SwaggerConfig is in common project that add to dependency into my microservice pom.
This my project configuration
SwaggerConfig
package com.project.common.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.bind.annotation.RequestMethod;
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.builders.ResponseMessageBuilder;
import springfox.documentation.service.ResponseMessage;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.List;
#Configuration
#EnableSwagger2
#Import({ BeanValidatorPluginsConfiguration.class })
public class SwaggerConfig {
#Value("${swagger.api.title: no title}")
private String title;
#Value("${swagger.api.package}")
private String apipackage;
#Value("${swagger.api.version:no version}")
private String version;
#Value("${swagger.api.description:no description}")
private String description;
#Bean
public Docket productApi() {
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors.basePackage(apipackage))
.paths(PathSelectors.any()).build().useDefaultResponseMessages(false)
.apiInfo(new ApiInfoBuilder().title(title).description(description)
.version(version).build())
.globalResponseMessage(RequestMethod.GET,defaultResponse())
.globalResponseMessage(RequestMethod.POST,defaultResponse())
.globalResponseMessage(RequestMethod.PUT,defaultResponse())
.globalResponseMessage(RequestMethod.DELETE,defaultResponse());
}
private static List<ResponseMessage> defaultResponse(){
return
List.of(new ResponseMessageBuilder().code(500).message("Internal server error").build(),
new ResponseMessageBuilder().code(400).message("bad request").build(),
new ResponseMessageBuilder().code(404).message("not found").build());
}
}
Main class
package com.project.company;
import com.project.common.config.SwaggerConfig;
import com.project.company.infrastructure.config.MyApplicationConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import java.util.ArrayList;
import java.util.List;
#SpringBootApplication(exclude={SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class})
#Import({MyApplicationConfig.class, SwaggerConfig.class})
public class MyCompanyApplication {
public static void main(String[] args) {
SpringApplication.run(MyCompanyApplication.class, args);
}
#Bean
public CommandLineRunner init(){
return (String... args)->{
// do something
};
}
}
I found my error. I forgot this dependency :
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-bean-validators</artifactId>
</dependency>

Spring Boot #ComponentScan finds candidate component class but does not inject #Configuration beans

I have #SpringBootApplication with #ComponentScan({"myPackage"}) and in myPackage I have a class annotated with #Configuration or #Component. When I start the spring boot app the logs show:
DEBUG [main] org.sprin.conte.annot.ClassPathScanningCandidateComponentProvider 437 scanCandidateComponents: Identified candidate component class: file [C:\Web\project\bin\main\myPackage\Config.class]
but then nothing injects the class or its beans into the app...
It looks related to this
CODE
package app;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.gemfire.config.annotation.EnableLogging;
import org.springframework.data.gemfire.repository.config.EnableGemfireRepositories;
#SpringBootApplication
#ComponentScan({"myPackage"})
#EntityScan({"myPackage"})
#EnableGemfireRepositories("region")
#EnableLogging(logLevel="info", logFile="geodeApi.log")
public class Web {
private static final Logger log = LogManager.getLogger(Web.class);
public static void main(String[] args) {
log.info("In Main");
SpringApplication app = new SpringApplication(Web.class);
app.setWebApplicationType(WebApplicationType.REACTIVE);
SpringApplication.run(Web.class, args);
log.info("Out Main");
}
}
In myPackage.Client
package myPackage;
import java.util.UUID;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import org.apache.logging.log4j.Logger;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.client.ClientRegionShortcut;
import org.apache.logging.log4j.LogManager;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.data.gemfire.cache.config.EnableGemfireCaching;
import org.springframework.data.gemfire.config.annotation.ClientCacheApplication;
import org.springframework.data.gemfire.config.annotation.EnableClusterDefinedRegions;
import org.springframework.data.gemfire.config.annotation.EnablePdx;
import org.springframework.data.gemfire.config.annotation.EnablePool;
import org.springframework.data.gemfire.config.annotation.EnablePool.Locator;
import org.springframework.data.gemfire.config.annotation.EnableStatistics;
import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession;
#ClientCacheApplication(name = "Web", logLevel = "debug")
#EnablePool(name = "webPool", subscriptionEnabled = true)
#EnableClusterDefinedRegions(clientRegionShortcut=ClientRegionShortcut.CACHING_PROXY)
#EnablePdx
#EnableStatistics
#EnableGemFireHttpSession(poolName = "webPool")
#EnableGemfireCaching
// #EnableWebFlux
public class Client {
private static final Logger log = LogManager.getLogger(Client.class);
#Resource
private Region<String, String> myAdmin;
#PreDestroy
public void onDestroy() throws Exception {
log.info("onDestroy");
String guid = UUID.randomUUID().toString().substring(0, 8).toUpperCase();
myAdmin.put(guid, "Web Shutdown");
log.traceExit();
}
#Bean
ApplicationRunner StartedUp(){
log.traceEntry("StartedUp");
return args -> {
String guid = UUID.randomUUID().toString().substring(0, 8).toUpperCase();
myAdmin.put(guid, "Web Started");
log.traceExit();
};
}
// Required to resolve property placeholders in Spring #Value annotations.
#Bean
static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
log.traceEntry("propertyPlaceholderConfigurer");
return new PropertySourcesPlaceholderConfigurer();
}
}
In myPackage.Config
package myPackage;
import org.apache.geode.cache.GemFireCache;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.client.ClientRegionShortcut;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.gemfire.client.ClientRegionFactoryBean;
#Configuration
public class Config {
private static final Logger log = LogManager.getLogger(Config.class);
#Bean("myRegion")
public Region<String, Object> myRegion(GemFireCache cache) {
log.traceEntry();
Region<String, Object> r = cache.getRegion("myRegion");
r.setUserAttribute(ClientRegionShortcut.CACHING_PROXY);
return r;
}
}
In Config class while defining the bean you are using Region<String, Object> as return type. Where as in the your Client class you define Region<String, String>. Here it is clearly a type mismatch and hence bean will not load.

#EnableScheduling not being recognized and creating Executor service and running scheduled jobs

Trying to modify an application to have a #Component that has a scheduled task to fire every n seconds. It seems like the executor service is never getting started to recognized there are #Components that have a #Scheduled annotation. Any ideas?
Ensured the packages are correct and should be in the componentscan base package.
package com.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* This is the Spring Boot class for the Data Consistency Model (DCM)
*/
#EnableScheduling
#SpringBootApplication
#EnableConfigurationProperties({KafkaConfig.class, SparkConfig.class, JedisConfig.class, PrometheusConfig.class})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Component Class:
package com.test;
import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.exporter.PushGateway;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.io.IOException;
#Component
#EnableScheduling
#EnableAsync
public class PrometheusGatewayMetricsPusher {
private static final Logger LOGGER = LogManager.getLogger(PrometheusGatewayMetricsPusher.class);
#Value("${spring.application.name}")
private String appName;
#Autowired
PushGateway pushGateway;
#Scheduled(fixedDelay = 1000, initialDelay = 1000)
public void push() {
try {
pushGateway.push(CollectorRegistry.defaultRegistry, appName);
} catch (IOException e) {
LOGGER.log(Level.ERROR, "Error pushing to gateway. " + e.getMessage());
}
}
}
Config Class:
package com.test;
import io.prometheus.client.exporter.PushGateway;
import io.prometheus.client.hotspot.DefaultExports;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
#Getter
#Setter
#Configuration
public class MetricsConfig {
#Value("prometheus.config.gateway")
private String pushGatewayURL;
#PostConstruct
public void defaultExports() {
DefaultExports.initialize();
}
#Bean
public PushGateway pushGateway() {
return new PushGateway("localhost:9091");
}
}
I would expect the executor service to be started and initialized in the Application Context with a Thread Pool of 1. Then it would execute the #Scheduled method every second after an initial delay of 1 second. If I breakpoint in the #Component class it isn't being initialized at all.

Resources