I'm using a 3rd party dependency in my Spring Boot project (version 2.6.3) which has the following classes:
#ConditionalOnProperty(prefix = "spring.cloud.vault", name = "enabled", matchIfMissing = true)
#AutoConfigureAfter(ApacheHttpClientAutoConfiguration.class)
#Configuration
public class VaultServiceAutoConfiguration {
// ...
}
#Configuration
#EnableConfigurationProperties({VaultServiceProperties.class})
#ConditionalOnBean(VaultServiceAutoConfiguration.class)
public class VaultServiceFacadeConfiguration {
private final VaultServiceProperties vaultServiceProperties;
#Autowired
public VaultServiceFacadeConfiguration(VaultServiceProperties properties) {
this.vaultServiceProperties = properties;
}
#Bean
#ConditionalOnMissingBean(VaultServiceFacade.class)
public VaultServiceFacade vaultServiceFacade(
#Qualifier("runtime") VaultServiceTemplate vaultServiceTemplate) {
// ...
}
}
I set spring.cloud.vault.enabled=true in my bootstrap.yml.
In my project I import the dependency and created a component class:
#Component
public class MyVault {
private VaultServiceFacade vaultServiceFacade;
public MyVault(VaultServiceFacade vaultServiceFacade) {
this.vaultServiceFacade = vaultServiceFacade;
}
}
in order to use VaultServiceFacade bean which provides methods to interact with Hashicorp Vault instance. The problem is that I get this error: No qualifying bean of type 'other.package.VaultServiceFacade' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
I don't understand why I get his error because my main class is annotated with #SpringBootApplication so that auto-configuration is enabled. In addition if I try to inject VaultServiceAutoConfiguration bean it works:
#Component
public class MyVault {
private VaultServiceAutoConfiguration v;
public MyVault(VaultServiceAutoConfiguration v) {
this.v = v;
}
}
EDIT: I did notice that the dependency has a file spring.factories with the following code:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
other.package.VaultServiceAutoConfiguration
So maybe only VaultServiceAutoConfiguration is "whitelisted" for auto-configuration, so I need to understand how to allow other beans from other.package to be injected in my project.
EDIT2: I managed to get this working by adding #ComponentScan on the MyVault class:
#ComponentScan("other.package")
#Component
public class MyVault {
private VaultServiceFacade vaultServiceFacade;
public MyVault(VaultServiceFacade vaultServiceFacade) {
this.vaultServiceFacade = vaultServiceFacade;
}
}
I still don't understand why the ComponentScan works only on when added to MyVault class but is if I scan for this package from main it class it doesn't work:
#SpringBootApplication(scanBasePackages = {"other.package"})
public class Application {
// ...
}
#ComponentScan just works because you're very directly asking Spring to scan said package for any beans which it straight up does.
I can't tell why #SpringBootApplication(scanBasePackages = {"other.package"}) doesn't work without trying it for myself but I guess the error you get is that the other.package beans get created and instead all other beans fail to exist (after all other.package is not the base package).
Finally, why doesn't you preferred conditional approach work?
Hard to tell without a simplified sample app to work with. I doubt it's because of VaultServiceAutoConfiguration, I've created a simplified project where the offending bean lies directly in said class and it loads just fine. Try moving your VaultServiceFacade definition to VaultServiceAutoConfiguration and remove #AutoConfigureAfter(ApacheHttpClientAutoConfiguration.class), if that works you know it's something in VaultServiceFacadeConfiguration (or #AutoConfigureAfter(ApacheHttpClientAutoConfiguration.class) itself, maybe #EnableConfigurationProperties({VaultServiceProperties.class})?
Also, I used application.properties instead of bootstrap.yml but that's unlikely to be it.
Feel free to send a sample simplified project to work on and test your assumptions
As the default value for the property is already true, I would not set it at all.
In order to explicitly configure the Facade try to
#Import(VaultServiceFacadeConfiguration.class)
in your SpringBootApplication.
Please check your dependencies. "other.package" looks very strange and does not look like a package name used by HashiCorp.
I'm a little new t working with Spring so any help provided would be great.
I have a SpringApplication class (annotated with #SpringBootApplication. In another class (within the same project), it contains a ServiceClass class. When the class is in the same project, it runs as expected.
When the ServiceClass is moved to an external jar, I get the following error.
Description:
Field service in
package-to-class.Comp required a
bean of type 'package-to-class.ServiceClass'
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
'package-to-class.ServiceClass' in your
configuration.
I am trying to find what I need to do to inject (#AutoWired) into my project with the above error.
By default, Spring Boot's component scanning only looks in the same package as the #SpringBootApplication and its descendants.
The approach I would suggest is using #Import to import specific beans from outside the project, or use #ComponentScan to import all beans from a package in another project.
#SpringBootApplication
#Import(ServiceClass.class)
public class SpringApplication {
// ...
}
or
#SpringBootApplication
#ComponentScan(basePackages = "com.example.mylibrary")
public class SpringApplication {
// ...
}
Okey some basic things, you have mixed up your packages a bit.
#SpringBootApplication will scan all classes in packages below the class this is annotated on. This annotation is an alias for #EnableAutoConfiguration, #Configuration and #ComponentScan means that #ComponentScan(basePackages = {"com.springdi.example"}, basePackageClasses = DependencyBasePackageClass.class) is not needed.
com.springdi.example // class with #SpringBootApplication annotation
|
|
|
com.springdi.example.* // Will find all #Service, #Component, #Configuration
// in subpackages below the #SpringBootApplication
// annotation
You can read more about the annotation here SpringBootApplication
Since your other annotated classes are NOT in the same package structure as the #SpringBootApplication you need to define all the places you want to scan for annotations.
#SpringBootApplication(scanBasePackages = {"com.springdi.example", "com.dependency.example"})
will probably include all the packages that you want to scan through.
I have a multi module project but I am having a problem with my configuration.
I have a my main method in package nl.example.hots.boot
#SpringBootApplication
#EnableAutoConfiguration
#ComponentScan(basePackages = {"nl.*"})
#EntityScan("nl.*")
public class HotsApplication {
public static void main(String[] args) {
SpringApplication.run(HotsApplication.class, args);
}
In the nl.example.hots.core.* package I have the class:
#Service
#AllArgsConstructor
#Transactional(propagation = Propagation.REQUIRED)
public class MapImportService {
private MapInputModelMapper mapInputModelMapper;
private MapEntityRepository mapEntityRepository;
public void add(final MapInputModel mapInputModel) {
System.out.println(mapInputModel.getName());
mapEntityRepository.save(mapInputModelMapper.mapToEntiy(mapInputModel));
}
and:
#Component
#Mapper
public interface MapInputModelMapper {
MapInputModel mapToInputModel(final MapEntity n);
MapEntity mapToEntiy(final MapInputModel n);
}
The repository is in the package nl.example.hots.persistence.*
I get the following error when running the application:
Description:
Parameter 0 of constructor in nl.example.hots.core.dataimport.MapImportService.MapImportService required a bean of type 'nl.timonschultz.hots.core.map.mapper.MapInputModelMapper' that could not be found.
Action:
Consider defining a bean of type 'nl.example.hots.core.map.mapper.MapInputModelMapper' in your configuration.
When I remove the #EnableAutoConfiguration and #ComponentScan annotations it works. The application starts without the bean error.
In that case however my restcontroller does not work anymore:
{
"timestamp": "2018-07-18T20:48:39.414+0000",
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/maps"
}
When I remove the MapImportService class (and the bean error doesn't pop up) it works on the same url.
package nl.example.hots.api.data_import;
#RestController
#AllArgsConstructor
public class ImportController {
private static final String URL = // a url
private Reader reader;
#RequestMapping("/maps")
public String abilityStreamImport() {
reader.readStream(URL); // calls a class in nl.example.hots.core.*
return "Greetings from APP!";
}
}
I tried several different combinations and I have a different project as and example where the annotations are used together and it works right. Can somebody explain why the annotations generate the bean error when used together? And why the controller gives an error when only using #SpringBootApplication?
In my Pom.XML the boot module has a dependency on the API layer that has a dependency on the core layer that has a dependeny on the persistence layer.
I'm using mapstruct and Lombok in the project.
--- edit: repository ---
#Entity(name = "MAPS")
#Builder
#NoArgsConstructor
#AllArgsConstructor
#Getter
public class MapEntity extends HasId<Long> {
private String name;
#ElementCollection
private List<String> translations;
}
#Repository
public interface MapEntityRepository extends JpaRepository<MapEntity, Long> {
}
#MappedSuperclass
public abstract class HasId<T> {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Setter
#Getter
private T id;
}
project structure:
hots-application;
- hots-api
- pom.xml
- nl.example.hots.api.dataimport.ImportController;
- hots-boot
- pom.xml
- nl.example.hots.boot.HotsApplication;
- hots-core
- pom.xml
- nl.example.hots.core.dataimport.mapImportService.MapImportService;
- nl.example.hots.core.map.mapper.MapInputModelMapper
- hots-persistence
- pom.xml
- nl.example.hots.persistence.common.HasId;
- nl.example.hots.persistence.map.MapEntity;
- nl.example.hots.persistence.map.MapEntityRepository;
pom.xml
Spring Boot will scan all the packages and sub packages starting with the package that the #SpringBootApplication annotated class is in. Your class is in nl.example.hots.boot scanning only that package. The other classes are in different, non-scanned packages.
Due to this package structure and not following the best practices you basically loose a lot of the auto configuration features (Spring Data JPA, ReST etc) and you have to resort to manually enabling/configuring that. Partially through adding additional #ComponentScan annotation, for JPA the #EntityScan annotations. But you would also need to add all the #EnableJpaRepository etc. annotations as those aren't added anymore (at least not with the right packages).
The fix is fairly easy. Move your #SpringBootApplication annotated class to the nl.example.hots package (as stated in the best practices). Remove the annotations other then #SpringBootApplication and simply start your application.
You're missing the #Autowired annotation on your #AllArgsConstructor, try:
#AllArgsConstructor(onConstructor = #__(#Autowired))
After some trial and error I managed to get it working for the most part.
I added the scanBasePackages = "nl" to the SpringBootApplication annotation.
Mapstruct did give me some trouble still however but when I removed it and made a quick mapper myself it all worked fine.
Thanks for all the help and suggestions and links to read up on! I'll keep the (bestpractice) suggestions in mind for my next project.
Below is my main class now
package nl.example.hots.boot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#SpringBootApplication(scanBasePackages = "nl")
#EntityScan("nl.*")
#EnableJpaRepositories("nl.*")
public class HotsApplication {
public static void main(String[] args) {
SpringApplication.run(HotsApplication.class, args);
}
}
Spring is not creating a MapInputModelMapperBean. I have never used MapStruct, but it kinda reminds me of mybatis. It looks weird to me that you annotate MapInputModelMapperBean with #Mapper and #Component. How is spring supposed to create the bean? Are you using some sort of spring-boot-mapstruct package that performs this magic?
I made a quick search and found this https://www.credera.com/blog/technology-solutions/mapping-domain-data-transfer-objects-in-spring-boot-with-mapstruct/, from which it seems like you would need something like:
#Mapper(componentModel = "spring")
public interface MapInputModelMapper
Which I guess will generate the implementation of the mapper with #Component on it or something similar.
The #SpringBootApplication annotation is equivalent to using #Configuration, #EnableAutoConfiguration and #ComponentScan with their default attributes.
The component scan default behaviour happens only in the same package and in its sub package. If your controllers or components are in different, dont forget to override your component scan default configurations.
Here is the sample code on how to override the default behavour.
#SpringBootApplication(scanBasePackages = "com.code")
Or you can specify multiple packages as shown below:
#SpringBootApplication(scanBasePackages = {"com.java2novice", "com.example"})
The #SpringBootApplication annotation is a convenience annotation that combines the #EnableAutoConfiguration, #Configuration and the #ComponentScan annotations in a Spring Boot application.
#EnableAutoConfiguration – This enables Spring Boot’s autoconfiguration mechanism. Auto-configuration refers to creating beans automatically by scanning the classpath.
#ComponentScan – Typically, in a Spring application, annotations like #Component, #Configuration, #Service, #Repository are specified on classes to mark them as Spring beans. The #ComponentScan annotation basically tells Spring Boot to scan the current package and its sub-packages in order to identify annotated classes and configure them as Spring beans. Thus, it designates the current package as the root package for component scanning.
You have used all these three annotations #SpringBootApplication , #EnableAutoConfiguration and #ComponentScan.
Instead use single annotation like #SpringBootApplication(scanBasePackages = "abc.def.ghi")
Here the HotsApplication class with more efficient annotation
#SpringBootApplication(scanBasePackages = "nl.example.hots")
public class HotsApplication {
public static void main(String[] args) {
SpringApplication.run(HotsApplication.class, args);
}
I have two Maven modules.
The first one, called "application", contains the spring boot Application class that just contains these lines:
package org.example.application;
#SpringBootApplication
#ComponentScan({"org.example.model", "org.example"})
public class Application {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
}
}
In the same Maven module and package, org.example.application, I have a RestController that uses a Component that in turn uses the components of the other Maven module described below.
The other Maven module, called "model", contains the spring boot components (crud-repositories, entities etc). All those classes are under the same package structure as the first Maven module (org.example) but in subpackages of that, like org.example.model.entities, org.example.model.repositories etc.
So, the flow is like this:
Maven module application in package org.example:
SpringBootApplication -> RestController -> MyComponent
And the components that should be autowired in MyComponent are the ones in the model Maven module under the package org.example.model.
But when I start the application I just get the error:
***************************
APPLICATION FAILED TO START
***************************
Description:
Field myRepository in org.example.MyComponent required a bean of type 'org.example.model.repositories.MyRepository' that could not be found.
Action:
Consider defining a bean of type 'org.example.model.repositories.MyRepository' in your configuration.
org.example.model.repositories.MyRepository does exist in Maven module "model" but cannot be found by the SpringBootApplication class!
As you can see, I have tried to explicitly define the scan components to:
#ComponentScan({"org.example.model", "org.example"}) but that does not seem to help.
So what have I done wrong?
The first thing that you should wonder is : why do you declare #ComponentScan while one of the goal of #SpringBootApplication is (among other things) to enable the component scan ?
From Spring Boot documentation :
The #SpringBootApplication annotation is equivalent to using
#Configuration, #EnableAutoConfiguration and #ComponentScan with their
default attributes
Note that when on the class of your Spring Boot Application, you declare #ComponentScan to specify a value as basePackages, it overrides the basePackages used by default by #SpringBootApplication that is the current package where the class resides. So to have as base package both the package of the Spring Boot Application class and the additional packages that were missing, you have to explicitly set them.
Besides basePackages is recursive. So to enable the scan both for classes locating in the "org.example" and "org.example.model" packages, specifying "org.example" is enough as "org.example.model" is a sub-package of it.
Try that :
#SpringBootApplication(scanBasePackages={"org.example"})
Or alternatively :
#SpringBootApplication
#ComponentScan("org.example")
When specify #EnableJpaRepositories/#ComponentScan/scanBasePackages in a Spring Boot Application ?
As you design your Spring Boot application layout, your have two cases :
1) case (to favor) where you use a package layout that provides the auto configuration of Spring Boot with zero configuration.
To summarize : if your classes annotated with Spring Bean stereotypes : #Component, #Repositories, #Repositories,... are located in the same package or a sub-package of the Spring Boot Application class, declaring only
#SpringBootApplication is all you need.
2) case (to avoid) where you don't use a package layout that provides the auto configuration of Spring Boot with zero configuration.
It generally means that you have candidate classes to scan that are not in the package (or sub-package) of your class annotated with #SpringBootApplication.
In this case, you add the scanBasePackages attribute or add #ComponentScan to specify packages to scan.
But additionally, if your repositories are not located in a package or sub-package of your class annotated with #SpringBootApplication, something else has to be declared such as : #EnableJpaRepositories(="packageWhereMyRepoAreLocated")
Here is the documentation about this part (emphasis is mine) :
80.3 Use Spring Data Repositories
Spring Data can create implementations of #Repository interfaces of
various flavors. Spring Boot handles all of that for you, as long as
those #Repositories are included in the same package (or a
sub-package) of your #EnableAutoConfiguration class.
For many applications, all you need is to put the right Spring Data
dependencies on your classpath (there is a
spring-boot-starter-data-jpa for JPA and a
spring-boot-starter-data-mongodb for Mongodb) and create some
repository interfaces to handle your #Entity objects. Examples are in
the JPA sample and the Mongodb sample.
Spring Boot tries to guess the location of your #Repository
definitions, based on the #EnableAutoConfiguration it finds. To get
more control, use the #EnableJpaRepositories annotation (from Spring
Data JPA).
Examples
1) case (to favor) where you use a package layout that provides the auto configuration of Spring Boot with zero configuration.
With a Spring Boot application declared in the org.example package, and all bean classes (Repositories included) declared in the same package or a sub-package of org.example, the following declaration is enough for the Spring Boot application :
package org.example;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
}
}
The repositories could be located in the org.example.repository package such as :
package org.example.repository;
#Repository
public interface FooRepository extends JpaRepository<Foo, Long>, { }
and
package org.example.repository;
#Repository
public interface BarRepository extends JpaRepository<Bar, Long>, { }
The controllers could be located in the org.example.controller package :
package org.example.controller;
#RestController
#RequestMapping("/api/foos")
public class FooController {...}
and so for...
2) case (to avoid) where you don't use a package layout that provides the auto configuration of Spring Boot with zero configuration.
With a Spring Boot application declared in the org.example.application package, and not all bean classes (Repositories included) declared in the same package or a sub-package of org.example.application, the following declaration will be required for the Spring Boot application :
package org.example.application;
#SpringBootApplication(scanBasePackages= {
"org.example",
"org.thirdparty.repository"})
#EnableJpaRepositories("org.thirdparty.repository")
public class Application {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
}
}
And the bean classes could be as below.
The repositories that may come from an external a JAR could be located in the org.thirdparty.repository package such as :
package org.thirdparty.repository;
#Repository
public interface FooRepository extends JpaRepository<Foo, Long>, { }
and
package org.thirdparty.repository;
#Repository
public interface BarRepository extends JpaRepository<Bar, Long>, { }
The controllers could be located in the org.example.controller package :
package org.example.controller
#RestController
#RequestMapping("/api/foos")
public class FooController {...}
and so for...
Conclusion : defining the Spring Boot application in the base package of your namespace is really encouraged to make the Spring Boot configuration as simple as possible.
I am getting the following error:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of method setApplicant in webService.controller.RequestController required a bean of type 'com.service.applicant.Applicant' that could not be found.
Action:
Consider defining a bean of type 'com.service.applicant.Applicant' in your configuration.
I have never seen this error before but it's odd that the #Autowire is not working. Here is the project structure:
Applicant Interface
public interface Applicant {
TApplicant findBySSN(String ssn) throws ServletException;
void deleteByssn(String ssn) throws ServletException;
void createApplicant(TApplicant tApplicant) throws ServletException;
void updateApplicant(TApplicant tApplicant) throws ServletException;
List<TApplicant> getAllApplicants() throws ServletException;
}
ApplicantImpl
#Service
#Transactional
public class ApplicantImpl implements Applicant {
private static Log log = LogFactory.getLog(ApplicantImpl.class);
private TApplicantRepository applicantRepo;
#Override
public List<TApplicant> getAllApplicants() throws ServletException {
List<TApplicant> applicantList = applicantRepo.findAll();
return applicantList;
}
}
Now I should be able to just Autowire Applicant and be able to access, however in this case it is not working when I call it in my #RestController:
#RestController
public class RequestController extends LoggingAware {
private Applicant applicant;
#Autowired
public void setApplicant(Applicant applicant){
this.applicant = applicant;
}
#RequestMapping(value="/", method = RequestMethod.GET)
public String helloWorld() {
try {
List<TApplicant> applicantList = applicant.getAllApplicants();
for (TApplicant tApplicant : applicantList){
System.out.println("Name: "+tApplicant.getIndivName()+" SSN "+tApplicant.getIndSsn());
}
return "home";
}
catch (ServletException e) {
e.printStackTrace();
}
return "error";
}
}
------------------------UPDATE 1-----------------------
I added
#SpringBootApplication
#ComponentScan("module-service")
public class WebServiceApplication extends SpringBootServletInitializer {
#Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(WebServiceApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(WebServiceApplication.class, args);
}
}
and the error went away but nothing happened. However when I commented out everything dealing with Applicant in the RestController prior to adding #ComponentScan() I was able to return a string the UI, thus meaning my RestController was working, now it is being skipped. I ugly Whitelabel Error Page now.
---------------------UPDATE 2------------------------------
I added the base package of the bean it was complaining about. Error reads:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of method setApplicantRepo in com.service.applicant.ApplicantImpl required a bean of type 'com.delivery.service.request.repository.TApplicantRepository' that could not be found.
Action:
Consider defining a bean of type 'com.delivery.request.request.repository.TApplicantRepository' in your configuration.
I added #ComponentScan
#SpringBootApplication
#ComponentScan({"com.delivery.service","com.delivery.request"})
public class WebServiceApplication extends SpringBootServletInitializer {
#Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(WebServiceApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(WebServiceApplication.class, args);
}
}
----------------------------Update 3----------------------
adding:
#SpringBootApplication
#ComponentScan("com")
public class WebServiceApplication extends SpringBootServletInitializer {
still is complaining about my ApplicantImpl class which #Autowires my repo TApplicantRepository into it.
It might be because the project has been broken down into different modules.
#SpringBootApplication
#ComponentScan({"com.delivery.request"})
#EntityScan("com.delivery.domain")
#EnableJpaRepositories("com.delivery.repository")
public class WebServiceApplication extends SpringBootServletInitializer {
There is a chance...
You might be missing #Service, #Repository or #Component annotation on your respective implementation classes.
Your Applicant class is not scanned it seems. By default all packages starting with the root as the class where you have put #SpringBootApplication will be scanned.
suppose your main class "WebServiceApplication" is in "com.service.something", then all components that fall under "com.service.something" is scanned, and "com.service.applicant" will not be scanned.
You can either restructure your packages such that "WebServiceApplication" falls under a root package and all other components becomes part of that root package. Or you can include #SpringBootApplication(scanBasePackages={"com.service.something","com.service.application"}) etc such that "ALL" components are scanned and initialized in the spring container.
Update based on comment
If you have multiple modules that are being managed by maven/gradle, all spring needs is the package to scan. You tell spring to scan "com.module1" and you have another module which has its root package name as "com.module2", those components wont be scanned. You can even tell spring to scan "com" which will then scan all components in "com.module1." and "com.module2."
Basically this happens when you have your Class Application in "another package". For example:
com.server
- Applicacion.class (<--this class have #ComponentScan)
com.server.config
- MongoConfig.class
com.server.repository
- UserRepository
I solve the problem with this in the Application.class
#SpringBootApplication
#ComponentScan ({"com.server", "com.server.config"})
#EnableMongoRepositories ("com.server.repository") // this fix the problem
Another less elegant way is to: put all the configuration classes in the same package.
In my case I had a terrible mistake. I put #Service up to the service interface.
To fix it, I put #Service on the implementation of service file and it worked for me.
If a bean is in the same package in which it is #Autowired, then it will never cause such an issue. However, beans are not accessible from different packages by default.
To fix this issue follow these steps :
Import following in your main class:
import org.springframework.context.annotation.ComponentScan;
add annotation over your main class :
#ComponentScan(basePackages = {"your.company.domain.package"})
public class SpringExampleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringExampleApplication.class, args);
}
}
Important:
For anybody who was brought here by googling the generic bean error message, but who is actually trying to add a feign client to their Spring Boot application via the #FeignClient annotation on your client interface, none of the above solutions will work for you.
To fix the problem, you need to add the #EnableFeignClients annotation to your Application class, like so:
#SpringBootApplication
// ... (other pre-existing annotations) ...
#EnableFeignClients // <------- THE IMPORTANT ONE
public class Application {
Side note: adding a #ComponentScan(...) beneath #SpringBootApplication is redundant, and your IDE should flag it as such (IntelliJ IDEA does, at least).
This can also happen if you are using Lombok and you add the #RequiredArgsConstructor and #NonNull for fields but some of your fields are not to be injected in the constructor. This is only one of the possibilities to get the the same error.
parameter 0 required a bean of type MissingBeanName that could not be found
In my case the error told me what Controller the problem was in, after removing #NonNull the application started fine
In my case these two options worked.
in //#ComponentScan ({"myapp", "myapp.resources","myapp.services"})
include also the package which holds the Application.class in the list, or
Simply add #EnableAutoConfiguration; it automatically recognizes all the spring beans.
I faced with familiar problem in my Maven multi-module project with Spring Boot 2. The problem was related to naming of my packages in sub Maven modules.
#SpringBootApplication incapsulate a lots of component like - #ComponentScan, #EnableAutoConfiguration, jpa-repositories, json-serialization and so on. And he places #ComponentScan in com.*******.space package. This part of packages com.*******.space must be common for all modules.
For fixing it:
You should rename all module packages. Other words you had to have in all packages in all Maven modules - the same parent part. For example - com.*******.space
Also you have to move your entry point to this package - com.*******.space
I think you can make it simplified by annotating your repository with #Repository, then it will be enabled automatically by Spring Framework.
It worked for me after adding below annotation in application:
#ComponentScan({"com.seic.deliveryautomation.mapper"})
I was getting the below error:
"parameter 1 of constructor in required a bean of type mapper that could not be found:
Moving the Springbootapplication(application.java) file to another package resolved the issue for me. Keep it separate from the controllers and repositories.
In my case this error appear because my import was wrong, for example, using spring, the import automatically appear:
import org.jvnet.hk2.annotations.Service;
but i needed:
import org.springframework.stereotype.Service;
I faced the same issue. Mongo DB repository was identified by Spring boot, but it was not creating Bean for a repository interface that extended the mongo repository.
The issue in my case was incorrect version specification in maven pom for "spring + mango". I have changed the artifact's group id and it all worked like magic. no annotations needed as spring boot took care of everything.
During my problem resolution, I was all over web searching for solutions and realized that this problem is actually project configuration related, anyone facing this issue should first check their project setup and enable debug from spring to get more details on failure and pay close attention to where exactly in the process, the creation has failed.
I sought online for an answer but it seems there is no one proper solution to my case:
At the very beginning, everything works well as follows:
#Slf4j
#Service
#AllArgsConstructor(onConstructor = #__(#Autowired))
public class GroupService {
private Repository repository;
private Service service;
}
Then I am trying to add a map to cache something and it becomes this:
#Slf4j
#Service
#AllArgsConstructor(onConstructor = #__(#Autowired))
public class GroupService {
private Repository repository;
private Service service;
Map<String, String> testMap;
}
Boom!
Description:
Parameter 4 of constructor in *.GroupService required a bean of type 'java.lang.String' that could not be found.
Action:
Consider defining a bean of type 'java.lang.String' in your configuration.
I removed the #AllArgsConstructor(onConstructor = #__(#Autowired)) and add #Autowired for each repository and service except the Map<String, String>. It just works as before.
#Slf4j
#Service
public class SecurityGroupService {
#Autowired
private Repository repository;
#Autowired
private Service service;
Map<String, String> testMap;
}
Hope this might be helpful.
This can happen if the #Service class is marked abstract.
#Configuration annotation will just solve the error
You'll also get this error if you accidentally define the same bean in two different classes. That happened to me. The error message was misleading. When I removed the extra bean, the issue was resolved.
My error was that I had included:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
instead of:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
It might help somebody. I had the same problem, same error message, same everything. I tried solutions from other answers, didn't help until I realised that the bean I am using has the same name as the one that is actually been autowired. It happened in the midst of refactor, thus I had to rename the class, which resulted positively. Cheers
Try configuring the project structure as given below:
Put all the repo, service, packages in the child package of the main package:
package com.leisure.moviemax; //Parent package
#SpringBootApplication
#PropertySource(value={"classpath:conf.properties"})
public class MoviemaxApplication implements CommandLineRunner {
package com.leisure.moviemax.repo; //child package
#Repository
public interface UsrRepository extends JpaRepository<UserEntity,String> {
This error message also pops up when you fail to annotate the Entity classes associated with your bean with the #Entity Annotation.
My ComponentScan worked fine but this popped up for the #repository interface:
#Repository
public interface ExpenseReportAuditRepository extends
PagingAndSortingRepository<ExpenseReportAudit, Integer> {
because I failed to add the #Entity annotation to ExpenseReportAudit
#Entity // <--- Adding this fixed the issue.
public class ExpenseReportAudit {
.....
#SpringBootApplication
#MapperScan("com.developer.project.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
I had a case where i need to inject RestTemplate into a service class. However, the RestTemplate cannot be picked up by the service class. What I did is to create a wrapper class under the same package as main application and mark the wrapper as Component and autowire this component in the service class. Problem solved. hope it also works for you
If your class dependency is managing by Spring then this issue may occur if we forgot to add default/empty arg constructor inside our POJO class.
There is a chance that you are trying to #autowired an interface before implement the interface.
example solution:
**HomeController.java**
class HomeController{
#Autowired
UserService userService;
.....
}
----------------------------------------------------------------------
**UserService.java**
public interface UserService {
User findByUsername(String username);
.....
}
-----------------------------------------------------------------------
**UserServiceImpl.java**
#Service
public class UserServiceImpl implements UserService{
public User findByUsername(String username) {
return userDao.findByUsername(username);
}
....
}
<i>This is not italic</i>, and [this is not a link](https://example.com)
In my case, our project has a Configuration class, so I just added mine like this
#Configuration
public class DependencyConfiguration {
#Bean
public ActivityService activityService(
#Value("${send.money.ms.activity.url}") final String activityHistoryUrl,
final HttpRestService httpRestService
) {
return new ActivityServiceImpl(activityHistoryUrl, httpRestService);
}
.......................
Then the microservice started alright.
PS: I encountered this issue even though the library I need is imported properly and could be seen on External Libraries imported.
Had the same error, transpired it was an issue with the application properties with incorrect username, password and driver and completely unrelated to Bean.
I also received a similar error:
Consider defining a bean of type 'A_REPOSITORY_INTERFACE' in your configuration.
Then, according to Akashe's solution, I added #EnableJpaRepositories to my main class. After that, I received the following error instead:
Consider defining a bean of type 'entityManagerFactory' in your configuration.
Next, I went through all the responses here, googled a lot and read a lot of other resources, which didn't worked out.
Finally, I was lucky to have found the solution on a blog/website (javatute.com). I just followed its examples.
Like suggested by many here, I added #ComponentScan("YOUR_BASE_PACKAGE.*") and #EntityScan("YOUR_BASE_PACKAGE.*") to my main app class, followed by adding a config package and creating a JpaConfig class like:
package YOUR_BASE_PACKAGE.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#Configuration
#EnableJpaRepositories(basePackages = "YOUR_BASE_PACKAGE")
public class JpaConfig {
}
The blog I followed:
Consider defining a bean of type in your configuration
which lead me to:
Error creating bean with name entityManagerFactory defined in class path resource : Invocation of init method failed
and finally to:
Many To Many Mapping In Hibernate/JPA Using Spring Boot And Oracle