Issue
I create this simple project to test a bug in another project. I have a main class (AppApplication) and a service class (CommandUser). The goal is to use the bean declared in class main on CommandUser class, and use the bean CommandUser, inside main class (as argument of run() method).
The first problem is whithout @ComponentScan({"com.example.app.*"}), the application don't start and report this:
Parameter 0 of constructor in com.example.app.CommandUser required a bean of type 'org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder' that could not be found.
It can't find Bcrypt bean, but it is defined in main class.
After put @ComponentScan({"com.example.app.*"}), it fix the problem with the Bcrypt bean, but report another error with missing of bean CommandUser in main class used as run() method argument:
Parameter 0 of method run in com.example.app.AclsApplication required a bean of type 'com.example.app.CommandUser' that could not be found.
Again, it can't find another bean, in this case, the CommandUser, a service class that I annotated with @Service annotation.
Without @ComponentScan, it recognized the CommandUser bean on Main Class (as run() method argument), but Bcrypt bean continue with the same problem.
I think the problem is with AppApplication class, because if I use the CommandUser bean, in another class it works.
The project struct is:
com.example.app/
> AppApplication
> CommandUser
Note: the classes are in the same level, I know that is wrong for real applications, but it is only a test.
AppApplication main class (with main()):
@ComponentScan({"com.example.app.*"})
@SpringBootApplication
public class AppApplication {
public static void main(String[] args) {
SpringApplication.run(AclsApplication.class, args);
}
@Bean
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Bean
CommandLineRunner run(CommandUser commandUser){
return args -> {
// ...
};
}
}
CommandUser service class (bean):
@Service
@RequiredArgsConstructor
public class CommandUser {
private final BCryptPasswordEncoder bCryptPasswordEncoder;
public void doSomething(String arg) {
// ...
}
}
Thanks in advance.
Solution
This is caused because in your CommandUser
class you are saying that you require a BCryptPasswordEncoder
, but the bean you are creating is a PasswordEncoder
. You can fix this by, preferably, modifying your CommandUser
class to inject the interface, like this:
@Service
@RequiredArgsConstructor
public class CommandUser {
private final PasswordEncoder passwordEncoder;
public void doSomething(String arg) {
// ...
}
}
Answered By - lane.maxwell
Answer Checked By - Mary Flores (JavaFixing Volunteer)