NoSuchBeanDefinitionException for bean defined in JavaConfig - spring

I was using XML configuration on my project earlier, and everything was working.
We're moving gradually to java config, so right now I'm at a stage where I'm using a mix of Java and XML configs.
Here's the problem, there is a bean defined in my XML config : beanA.
<bean id="beanA" class="BeanA" />
The class BeanA has an autowired dependency on BeanB.
class BeanA {
#Autowired
BeanB beanB;
}
Earlier, this beanB was also in XML config, and it ran correctly.
Now, I have made this change, and it is no longer working :
#Configuration
class MyConfig {
#Bean
public BeanB beanB() {
return new BeanB();
}
}
Apart from adding #Configuration and #Bean annotations, is there something else required to do that I am missing?
I'm getting the following error :
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'beanB': Unsatisfied dependency expressed through field 'beanA';
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.xxxxxx.yyy.zzzzzzzzzzzz.abc.beanA' available:
expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Please note,
I have only moved beanB to be created via java config.
BeanA actually has more dependencies, so I cannot move it to java config at this stage (will be doing proper migration later).

you need to add configuration for BeanB as well in the xml configuration. as when the program is run it loads all the bean definition from xml configuration file. So it looks like BeanB definition is missing in configuraion file.

Spring does not load the beans from the classes annotated with #Configuration unless it has been told to look for classes with this annotation.
To make spring look for these classes, the following must be added in your xml configuration :
<context:component-scan base-package="com.xxxxx.yyy.zzzz">
It will then recursively find and initialize all the beans in the package com.xxxxx.yyy.zzzz.

Related

Application Context is failing to load, as it is not finding any qualifying bean of type EntityManager

While running JUnits, ApplicationContext is not loaded, as it could not find a qualifying bean javax.persistence.EntityManager. However, the application for which the Junit is being written is working. Both the application and JUnits are using the same spring configuration.
My Configuration class looks like below
#Configuration
#EnableTransactionManagement
public class AppConfiguration {
#Autowired private EntityManager entityManager;
#Override #Bean
public CustomRepository<Person> customRepository(){
return new CustomRepository<>(Person.class, entityManager);
}
As you see, I'm able to autowire EntityManager, even though I have not explicitly defined the bean and the application is working without any issues.
Now in my JUnit
#RunWith(SpringRunner.class)
#ContextConfiguration(classes=AppConfiguration.class)
#TestPropertySource(locations = "classpath:application.properties")
public class ControllerTest {
#Autowired
private CController controller;
As you see both application and my Junit are using same configuration. How ever when running JUnit, I'm seeing
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.persistence.EntityManager' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
I could not understand what in the JUnit is causing the isssue, while the aplication is still working.
Thanks
it clearly means that EntityManager bean is not defined in your application context.
So either you define it by yourself or let Spring-boot do the lifting(Spring-boot auto config your context based on dependencies in your POM file). If you choose the latter option then one option to get rid of the error by adding H2 DB.
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
UPDATE:
In your test, instead of initializing your context using #ContextConfiguration do that with #SpringBootTest it will bootstrap your entire container(including other beans that are not defined in AppConfiguration.java). Read more about in spring-docs

Spring componentscan for multiple packages

I want Spring to perform dependency injection from 2 different projects and have a main #Configuration annotated class as below -
#Configuration
#EnableWebMvc
#ComponentScan(value = { "com.x.y", "com.a.b" })
public class AppConfig {
}
Classes under com.x.y is part of packages which contains AppConfig class but classes under com.a.b are part of different jar which is packaged under war file containing AppConfig class.
When i am deploying war file i am getting error as -
Unsatisfied dependency expressed through constructor argument with index 0 of
type [com.a.b.c.d.ClassA]: No qualifying bean of type [com.a.b.c.d.ClassA]
found for dependency: expected at least 1 bean which qualifies as autowire
candidate for this dependency. Dependency annotations: {}; nested exception
is org.springframework.beans.factory.NoSuchBeanDefinitionException:
I am not sure what is wrong in my way of using #ComponentScan. Looking for inputs from Spring experts.
Thanks

External Java Library issue with Autowiring and injecting bean

I have created a Spring Boot application managed by Maven.
I'm retrieving an company's library from our Maven repository.
In this library, we have a service interface, not being annotated with '#Service':
public interface MyService {
//...
}
This service has only one implementation :
public class DefaultMyService implements MyService {
//...
}
This library context is managed the old Spring way (in applicationContext.xml file).
I read that normally, Spring Boot is able to find the implementation if there's only one in the scope.
When I try to run "spring-boot:run" on my project, it will fail with the following error :
No qualifying bean of type 'com.pharmagest.saml.SAMLService'
available: expected at least 1 bean which qualifies as autowire
candidate. Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}
I tried:
To add a #ComponentScan on the configuration class, including packages in error : #ComponentScan(basePackages={"com.mycompany.web", "com.mycompany.thelibrary.client.*", "com.mycompany.thelibrary.services.*"})
To add the bean definition in applicationContext.xml (if I add the interface it tells me it can define it, thus I heard that Spring can find the default implementation if there is only one ?)
To add library at "runtime" in projects options
To add the library as external resource not via maven
In all cases I just can maven build but can't run the project.
Do you have any advice to help me ? thanks!
Won't work as the DefaultMyService has no #Component (or #Service) annotation will not be detected.
Bean definition has to be a concrete instance so use DefaultMyService instead of the interface. Spring will not detect anything for you your understanding is wrong
and 4. Will not change anything only adding dependencies without proper 1. or 2. will do nothing.
Just add a #Bean to your configuration
#Bean
public DefaultMyService myService() {
return new DefaultMyService();
}
Or import the other libraries applicatiponContext.xml which is what you probably should do.
#ImportResource("classpath:/applicationContext.xml")
Add this next to the #SpringBootApplication.

Initialize bean while project deployment spring

I was asked in one of interview that how we can initialize bean while project deployment in Spring ?
There are several options:
Your bean can implement InitializingBean interface and initialization work can be done inside afterPropertiesSet() method
You can just add a method in a bean class and annotate it with #PostConstruct
You can add method in a bean class and mark it as an init method. Using xml config the bean definition would look like this:
<beans>
<bean id="myBean" class="..." init-method="init"/>
</beans>
And using Java config like this:
#Bean(initMethod="init")
public MyBean myBean() {
return new MyBean();
}
You can also implement your own BeanPostProcessor and provide implementation in postProcessAfterInitialization or postProcessBeforeInitialization methods.
One caveat: all this initialization logic is a part of bean lifecycle, which doesn't mean that it will be invoked during the project deployment.
However if bean is a singleton bean then by default it is created during the spring context start up. I guess it is what you mean by project deployment.

Autowire Spring XML bean inside Spring JavaConfig

I have a xml bean definition and JavaConfig bean definition in the same project. The JavaConfig need to reference the XML bean. But When i autowire the xml bean definition inside JavaConfig I get NoSuchBean definition error. My question is: Isnt the xml beans and JavaConfig beans visible to each other? If not how do i inject the xml bean into JavaConfig? Thanks
Edit:
Changing #Autowire to #Resource fixed it, but i dont understand why. Autowire should go after type and the XML bean is of the type Autowire is annoted with.
If your bean is not being picked up by Autowire, you need to ensure the configuration file for the beans is being read and in turn is generating the beans.
One easy way to check is if you are using an IDE with Bean detection capability to see if the IDE is picking up the bean.
If this is working then please paste in your code of the xml with bean in it and xml containg your scan ability.

Resources