main Class:
package *.*.*;
#SpringBootApplication
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
}
DBUtils.java
package *.*.*.dataaccess.dbutils;
#Service
public class DBUtils {
#Autowired
UserRepository userRepository;
public UserEntity getUserEntityById(String id) {
return userRepository.findById(id);
}
}
Repository Class:
package *.*.*.dataaccess.repository;
#Repository
public interface UserRepository extends JpaRepository<UserEntity, UserIdentity> {
UserEntity findById(String id);
}
and also UserEntity java class is in package *.*.*.dataaccess.dao;
Test Class:
#SpringBootTest
class UserApplicationTests {
#Autowired
DBUtils utils; // issue is with this
#Test
void contextLoads() {
}
}
While doing maven test for entire project and getting the below error:
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'DBUtils': Unsatisfied dependency expressed through field 'userRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type '...dataaccess.repository.UserRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type '...dataaccess.repository.UserRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
I have used #Service on DBUtils and #Repository on JpaRepository but still getting the above error and using springboot is 2.4.1.
Can anyone please help here?
I'm trying to use JPA for my spring application. I have integrated the JPATransactionManager & LocalEntityManagerFactoryBean into AppConfig class. Now, when I try to call one of the method which is in DaoImpl, the AppConfig is not able to Autowire the classes. Here is my code
Test Class
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
BbDao personService = context.getBean(BbDao.class);
personService.getDealByDealId("0194541605021NJMAPFU");
context.close();
}
}
AppConfig
#Configuration
#EnableWebMvc
#EnableTransactionManagement
#ComponentScan(basePackages = "net.bb.spring")
public class AppConfig{
#Bean
public LocalEntityManagerFactoryBean getEntityManagerFactoryBean() {
LocalEntityManagerFactoryBean factoryBean = new LocalEntityManagerFactoryBean();
factoryBean.setPersistenceUnitName("MyPersistence");
return factoryBean;
}
#Bean
public JpaTransactionManager geJpaTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(getEntityManagerFactoryBean().getObject());
return transactionManager;
}
}
ConfirmPurchaseController
#RestController
public class ConfirmPurchaseController {
private Logger logger = Logger.getLogger(ConfirmPurchaseController.class);
#Autowired
private MyService myService;
#GetMapping("/purchase")
public ResultDto confirmpurchase(HttpServletResponse response) throws ClassNotFoundException, IOException {
// Business Logic
}
}
MyService
#Component
public interface MyService {
// Methods defined
}
MyServiceImpl
#Service
public class MyServiceImpl implements MyService, ServletContextAware {
private ServletContext servletContext;
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
public ServletContext getServletContext() {
return servletContext;
}
// Added the implemented methods of the MyService Interface
}
The exception it throws is
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myServiceImpl': Unsatisfied dependency expressed through field 'servletContext'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.servlet.ServletContext' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
and the error log is
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'confirmPurchaseController': Unsatisfied dependency expressed through field 'myService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myServiceImpl': Unsatisfied dependency expressed through field 'servletContext'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.servlet.ServletContext' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:84)
at net.bb.spring.controller.Test.main(Test.java:14)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myServiceImpl': Unsatisfied dependency expressed through field 'servletContext'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.servlet.ServletContext' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 14 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.servlet.ServletContext' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1493)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 27 more
Any ideas would be very helpful for me.
P.S : Im using configuration as annotations, no XML
It is not an answer, however I cannot add a comment yet.
Did you try to autowire a ServletContext via setter method?
- remove #Autowired from property
- remove one of your setters for context (unnecessary duplication)
- mark a setter as #Autowired
Moreover remove #Component annotation from MyService, it is unnecessary if you are using #Service annotation in its implementation.
As per Apache Tomcat documentation, a ServletContext
Defines a set of methods that a servlet uses to communicate with its
servlet container.
There is one context per "web application" per Java Virtual Machine.
(A "web application" is a collection of servlets and content installed
under a specific subset of the server's URL namespace such as /catalog
and possibly installed via a .war file.)
Which means that a ServletContext is only valid within a Servlet Container like Apache Tomcat. But as I can see, you are trying to run a normal Java application by creating beans in a main method, which makes the existence of ServletContext invalid.
So what you have to do is:
STEP 1: Build your AppConfig and override required methods.
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = {"net.bb.spring"})
public class AppConfig extends WebMvcConfigurerAdapter {
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/WEB-INF/");
}
//....
}
STEP 2: Create WebInitializer to initialize Dispatcher Servlet
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] {AppConfig.class};
}
#Override
protected String[] getServletMappings() {
return new String[] {"/"};
}
}
STEP 3: Create your Service layer to autowire ServletContext
#Service
public class MyServiceImpl implements MyService {
private ServletContext servletContext;
#Autowire
public MyServiceImpl(ServletContext servletContext) {
this.servletContext = servletContext;
}
public ServletContext getServletContext() {
return servletContext;
}
//...
}
STEP 4: Build your application to a WAR file
STEP 5: Deploy your WAR file to webapp folder of Tomcat (If you are using Tomcat)
STEP 6: Start Tomcat
Here is what you need to change:
1) You don't need to annotate the interface with #Component, annotation is required only on the implementation class
MyService
public interface MyService {
// Methods defined
}
2) Use constructor injection to obtain an instance of ServeletContext.
#Service
public class MyServiceImpl implements MyService, ServletContextAware {
private ServletContext servletContext;
#Autowire
public MyServiceImpl(ServletContext servletContext) {
this.servletContext = servletContext;
}
//TODO: other methods goes here...
}
pay attention that ServletContext is not a Spring bean and it can, therefore, not be injected unless you implement ServletContextAware. keep your implementation class implements ServletContextAware
In our project we have a structure similiar to code below. If I uncomment the specified block Spring will fail to autowire PrintService in the PrintController
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'PrintController': Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private printService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [MyPrintService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Why is Spring having issues with it?
#Controller
public class PrintController {
#Autowired
private MyPrintService printService;
}
#Service
public class MyPrintService extends AbstractPrintService<MyModel> {
/* uncomment this block to get error
#Override
public void print(MyModel model){
//do stuff
}*/
}
public abstract class AbstractPrintService<M> extends CommonAbstractPrintService<M> {
}
public abstract class CommonAbstractPrintService<M> implements PrintService<M> {
#Override
public void print(M model){
//do common stuff
}
}
public interface PrintService<M> {
void print(M model);
}
The solution was to autowire the bean using interface. So instead of:
#Autowired
private MyPrintService printService;
I used
#Autowired
private PrintService printService;
And it suddenly worked. But I have no Idea why Spring was offended by that override. Would be glad if anyone could explain that! Thanks!
I have below class files and it looks everything fine but i am not understanding why i am getting autowire failure. Can anyone please help me to find the issue?
updated with package details
package com.ui.controller;
#RestController
#RequestMapping(value = "/Person")
public class PersonController {
#Autowired
#Lazy
private RepoService repoService;
}
package com.messaging.service.impl;
#Component
#Lazy
public class RepoServiceImpl implements RepoService {
#Autowired
#Qualifier("personRepository")
private PersonRepository personRepo;
}
package com.messaging.service;
public interface RepoService {
}
package com.da.repository;
#Repository("personRepository")
public interface PersonRepository extends MongoRepository<SomeType, String> {
}
package com.conf;
#Configuration
#EnableMongoRepositories(basePackages = "com.da.repository")
#EnableMongoAuditing
#Profile("mongo")
public class MongoConfig extends AbstractMongoConfiguration {
}
I am getting following error:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.da.repository.PersonRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true), #org.springframework.beans.factory.annotation.Qualifier(value=personRepository)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1301)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1047)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
... 52 more
Its my bad. The issue was not with the above coding but with the mongodb connection. There was a connection issue which resulted the above error.
Application-Context is correctly setup!
Heres my class scenario
public interface IManager
{
public void doStuff();
}
#Component
public abstract class ManagerAction implements IManager
{
#Async
#Override
public void doStuff()
{
//doing stuff
}
public abstract manageWorker();
}
#Component
public class Working extends ManagerAction
{
#Override
public manageWorker()
{
//some busy code
}
}
#Component
public class NotWorking extends ManagerAction
{
#Override
public manageWorker()
{
//some busy code
}
}
#Service
public class BusinessWorker
{
#Autowire
private IManager manager_;
public void preformTasks()
{
manager_.doStuff();
}
}
Heres my error
ERROR [main] (ContextLoader.java:307) - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'BusinessWorker': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.B
eanCreationException: Could not autowire field: private com.background.IManager com.background.BusinessWorker.manager_; nested exception is org.springframework.beans.
factory.NoSuchBeanDefinitionException: No matching bean of type [com.background.IManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for
this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.background.IManager com.background.BusinessWorker.manager_;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.background.IManager] found for dependency: expected at least 1
bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:506)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
... 28 more
Application-Context
<mvc:annotation-driven />
<task:annotation-driven />
<context:annotation-config />
<context:component-scan base-package="com.background" />
The error message says it all: you try to autowire an instance of IManager, but two different Spring components implement this interface, so Spring doesn't know which one to autowire. You need to use the #Qualifier annotation to specify which one you want Spring to autowire.