Missing bean in controller even after adding ComponentScan annotation - spring-boot

I am trying to run a spring boot application which gets a list of names of people from the database. I am getting the below error :
Description:
Field peopleserviceinterface in com.sample.lombpackdemo.controller.FriendController required a bean of type 'com.sample.lombpackdemo.service.FriendsServiceInterface' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.sample.lombpackdemo.service.FriendsServiceInterface' in your configuration.
package com.sample.lombpackdemo.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.sample.lombpackdemo.entity.Friends;
import com.sample.lombpackdemo.rowmapper.FriendsRowMapper;
import com.sample.lombpackdemo.service.FriendsServiceInterface;
#CrossOrigin(origins = { "http://localhost:3000"})//to allow access from other servers
#RestController
#RequestMapping("/code")
#ComponentScan(basePackages="com.sample.lombpackdemo.service")
public class FriendController {
#Autowired
private FriendsServiceInterface peopleserviceinterface;//autowire the service
#GetMapping("/all")
public ResponseEntity<List<Friends>> getAllPeople(){
List <Friends> listOfAllPpl = peopleserviceinterface.getAllFriends();
System.out.println("Getting all friends"+listOfAllPpl.toString());
return new ResponseEntity<List<Friends>>(listOfAllPpl,HttpStatus.OK);
}
}
The FriendServiceInterface class is as below:
package com.sample.lombpackdemo.service;
import java.util.List;
import org.springframework.stereotype.Component;
import com.sample.lombpackdemo.entity.Friends;
#Component
public interface FriendsServiceInterface {
public List<Friends> getAllFriends();
}
The FriendService class:
package com.sample.lombpackdemo.service;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.sample.lombpackdemo.entity.Friends;
import com.sample.lombpackdemo.repos.FriendsRepo;
import com.sample.lombpackdemo.rowmapper.FriendsRowMapper;
#Service
#Profile("devel")//added to disable CORS only on development time
#Configuration
#Component
public class FriendService implements FriendsServiceInterface {
#Autowired
private FriendsServiceInterface peopleserviceinterface;
#Autowired
private FriendsRepo pplRepo;//should always autowire repository
#Autowired
private JdbcTemplate jdbc;
private static long idCounter = 0;
//FriendsRowMapper fRowMap=new FriendsRowMapper();
#Override
public List<Friends> getAllFriends() {
String sql="select f_name from list_friends";
return jdbc.query(sql, new FriendsRowMapper() );
/*
List<Friends> ppList= (List<Friends>) fRowMap.findAll();
try {
System.out.println("Repository value"+pplRepo.findAll());
System.out.println("Inside findAll of service class" +ppList.toString() );
}
catch(Exception e)
{
}
return ppList;
//
*/}
#Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
//registry.addMapping("/save-javaconfig").allowedOrigins("http://localhost:3000");
}
};
}
Please let me know what else needs to be changed. I have tried adding Component annotation to FriendService class and ComponentScan annotation to the controller class.
Edited to add JdbcConfig class
package com.sample.lombpackdemo.repos;
//import java.util.logging.Logger;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
#Configuration
#ComponentScan(basePackages = "com.sample.lombpackdemo")
public class SpringJdbcConfig {
protected final Logger log = LoggerFactory.getLogger(getClass());
#Bean
public DataSource mysqlDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/person_example");
dataSource.setUsername("root");
dataSource.setPassword("subfio");
return dataSource;
}
#Bean(name = "dbProductService")
#ConfigurationProperties (prefix = "spring.datasource")
#Primary public DataSource createProductServiceDataSource()
{ System.out.println("Inside db cofig ");
return DataSourceBuilder.create().build(); }
}
}

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

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>

#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.

How do you setup a resource server in spring boot that only uses role from the jwt token to allow access?

I think I have some odd requirements here because no matter where I look, I can't a specific example for what I was asked to do. I created a dummy project called contacts to test this. I am suppose to secure my api with Oauth2, but the authorization server is not on the same box.
It is my understanding that the client will need to call the authorization to get a token and then the request with the token will be sent to my api.
In my server the scope will determine if the user has access. I am not doing any authentication on my server.
I can't seem to get this to work though.
Controller
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping(value = "/contacts")
#PreAuthorize("#oauth2.hasScope('ec.edm.mdm')")
public class ContactsController {
#Autowired
ContactRepository customerRepo;
#RequestMapping(method = RequestMethod.GET, produces = { "application/json" })
public Page<Contact> findAllContacts(Pageable pagable) {
return customerRepo.findAll(pagable);
}
}
Application
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.Environment;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler;
#EnableResourceServer
#SpringBootApplication
public class App {
private static final Logger LOG = LoggerFactory.getLogger(App.class);
#Autowired
private Environment environment;
public static void main(String[] args) throws Exception {
SpringApplication.run(App.class, args);
}
/**
* Allows for #PreAuthorize annotation processing.
*/
#EnableGlobalMethodSecurity(prePostEnabled = true)
protected static class GlobalSecurityConfiguration extends GlobalMethodSecurityConfiguration {
#Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new OAuth2MethodSecurityExpressionHandler();
}
}
}

How and where to add new bean in Sping application generated by Jhipster

I generated my Spring application using Jhipster. Now I want to add controller for FilesUpload, and StorageService for it. But when I run my application it gets me this message
Description:Parameter 0 of constructor in com.kongresspring.myapp.web.rest.FileUploadResource required a bean of type 'com.kongresspring.myapp.service.StorageService' that could not be found.
Action:Consider defining a bean of type 'com.kongresspring.myapp.service.StorageService' in your configuration.
I can't find beans.xml to add new bean. I'm new in spring, so maybe there's some other way to configure bean, I'm not familiar whit. Here's my code for uploading file controller:
package com.kongresspring.myapp.web.rest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.kongresspring.myapp.service.StorageService;
#RestController
#RequestMapping("/api")
public class FileUploadResource {
private final Logger log = LoggerFactory.getLogger(FileUploadResource.class);
private final StorageService storageService;
#Autowired
public FileUploadResource(StorageService storageService) {
this.storageService = storageService;
}
/**
* POST uploadFile
*/
#PostMapping("/upload-file")
public String uploadFile(#RequestParam("file") MultipartFile file,
RedirectAttributes redirectAttributes) {
storageService.store(file);
redirectAttributes.addFlashAttribute("message",
"You successfully uploaded " + file.getOriginalFilename() + "!");
return "success";
}
/**
* GET preview
*/
#GetMapping("/preview")
public String preview() {
return "preview";
}
}
And here's my StorageService code:
package com.kongresspring.myapp.service;
import org.springframework.core.io.Resource;
import org.springframework.web.multipart.MultipartFile;
import java.nio.file.Path;
import java.util.stream.Stream;
public interface StorageService {
void init();
void store(MultipartFile file);
Stream<Path> loadAll();
Path load(String filename);
Resource loadAsResource(String filename);
}
You can create an implementation for StorageService, and annotate it as #Service/#Component, spring will automatically discover the bean:
#Service
public class StorageServiceImpl implements StorageService {
void init(){// You code goes here/}
void store(MultipartFile file){///}
Stream<Path> loadAll(){///}
Path load(String filename){//}
Resource loadAsResource(String filename){///}
}

Resources