I have a problem with SpringBoot in a personal project that I am doing in Visual Studio Code to be able to learn the language, the error is when implementing the security part, for some reason this error prevents the application from being deployed and therefore I cannot see login, the error occurs in SecurityConfiguration. The error that appears is this:
Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
08:24 ERROR 18740 --- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Field usuarioServicio in com.example.demo4.security.SecurityConfiguration required a bean of type 'com.example.demo4.service.UsuarioServiceImpl' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
My class SecurityConfiguration:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
@Autowired
private UsuarioServiceImpl usuarioServicio;
PasswordEncoder passwordEncoder;
AuthenticationManager authenticationManager;
@Bean
public SecurityFilterChain filterChain (HttpSecurity http) throws Exception{
AuthenticationManagerBuilder builder =http.getSharedObject(AuthenticationManagerBuilder.class);
builder.userDetailsService(usuarioServicio).passwordEncoder(passwordEncoder);
authenticationManager = builder.build();
http.authenticationManager(authenticationManager);
http.csrf(csrf -> csrf.disable());
http.cors(Customizer.withDefaults());
http.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
http.authorizeHttpRequests(auth -> auth.requestMatchers("/registro", "/js/","/css/", "/img/")
.permitAll()
.anyRequest()
.authenticated());
//http.exceptionHandling(exc -> exc.authenticationEntryPoint(null))
return http.build();
}
@Bean
public BCryptPasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Bean
public DaoAuthenticationProvider authenticationProvider(){
DaoAuthenticationProvider auth = new DaoAuthenticationProvider();
auth.setUserDetailsService(usuarioServicio);
auth.setPasswordEncoder(passwordEncoder());
return auth;
}
}
My class UsuarioServiceImpl:
@Service
public class UsuarioServiceImpl implements UsuarioService {
@Autowired
private BCryptPasswordEncoder passwordEncoder;
@Autowired
private UsuarioDao usuarioDao;
@Override
public Usuario guardar(UsuarioRegistroDTO registroDTO) {
Usuario usuario = new Usuario(registroDTO.getNombre(),
registroDTO.getApellido(), registroDTO.getEmail(),
passwordEncoder.encode(registroDTO.getPassword()),
Arrays.asList(new Rol("ROLE_USER")));
return usuarioDao.save(usuario);
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Usuario usuario = usuarioDao.findByEmail(username);
if(usuario == null) {
throw new UsernameNotFoundException("Usuario o password invalidos");
}
return new User(usuario.getEmail(), usuario.getPassword(), mapearAutoridadesRoles(usuario.getRoles()));
}
private Collection<? extends GrantedAuthority> mapearAutoridadesRoles(Collection<Rol> roles) {
return roles.stream().map(role -> new SimpleGrantedAuthority(role.getNombre())).collect(Collectors.toList());
}
}
My class UsuarioService:
public interface UsuarioService extends UserDetailsService{
public Usuario guardar(UsuarioRegistroDTO registroDTO);
}
My class RegistroUsuarioControlador:
@Controller
@RequestMapping("/registro")
public class RegistroUsuarioControlador {
@Autowired
private UsuarioServiceImpl usuarioServicio;
@ModelAttribute("usuario")
public UsuarioRegistroDTO retornarNuevoUsuarioRegistroDTO() {
return new UsuarioRegistroDTO();
}
@GetMapping
public String mostrarFormularioDeRegistro(){
return "registro";
}
@PostMapping
public String registrarCuentaDeUsuario(@ModelAttribute("usuario") UsuarioRegistroDTO registroDTO){
usuarioServicio.guardar(registroDTO);
return "redirect:/registro?exito";
}
}
My pom.xml :
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo4</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo4</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity6</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-rsa -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-rsa</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
</plugins>
</build>
</project>
My Demo4Application:
package com.example.demo4;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Demo4Application {
public static void main(String[] args) {
SpringApplication.run(Demo4Application.class, args);
}
}
aplication.properties:
server.port=8082
logging.pattern.dateformat=hh:mm
spring.main.banner-mode=off
spring.thymeleaf.cache=false
#Mysql conexion
spring.datasource.url=jdbc:mysql://localhost/dbd?useSSL=false&serverTimeZone=UTC&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.password=pswd
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
#Mostrar SQL
spring.jpa.properties.hibernate.forma_sql=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type-descriptor.sql.BasicBinder=TRACE
#crear bdd
spring.jpa.hibernate.ddl-auto= create
# security
spring.security.user.name=usuario
spring.security.user.password=psw
I have been trying to correct it with some answers to similar questions here, but for example by putting the class with the tag @Autowired(required=true) in the variable userService of type UserServiceImpl I have not been able to fix it, in fact my error is also replicated in RegistryUserController .Java.
I have also seen that it is likely that the folder distribution is not done well, but I don’t know what would be wrong in my case. If you need more information or for me to provide you with more code, I can attach it.
I took the tutorial I’m following from here although I updated it because many libraries were obsolete(the tutorial is in spanish):
https://www.youtube.com/watch?v=0wTsLRxS3gA
Can anyone help me solve this error?
Thanks in advance.
2
Answers
In the Spring Boot application, the dependency injection is performed by IOC container.
To annotate the java class as a Spring been needs to annotate the interface or class with proper annotation.
Maybe you should list the path to the folder where the class is located, I mean UsuarioServiceImpl, which may not have been scanned by spring.
In addition, a good course can greatly improve the efficiency of learning, and perhaps you should spend more time looking for a good course than you spend more time studying a relatively old one. This is just my personal advice. Good luck with your study.