I am using another application's service,since everything is already made and done.
My application is to use the interface class inside the application jar.
but something seem to be wrong when this code is called.
BeanFactory factory = new ClassPathXmlApplicationContext( "/Context-Controller.xml");
even if my Context-Controller.xml has this code
<context:component-scan base-package="com.package" />
My error.
Caused by:
org.springframework.beans.factory.NoSuchBeanDefinitionException:
No unique bean of type
[com.package.ServiceIamUsing] is
defined: Unsatisfied dependency of
type [interface
com.package.ServiceIamUsing]: expected
at least 1 matching bean
this is how i autowired it on my applciation.
public class MyAppDao implements IMyAppDao {
#Autowired
#Qualifier("serviceIamUsing")
private ServiceIamUsing serviceIamUsing;
//More codes here
}
jay, try the following:
- eliminate the forward-slash "/"
- in your application context xml file, try to import the application context from your external jar file if it has any --> import resource="classpath*:/META-INF/spring/*.xml"
let me know if it does/doesn't work.
Is there, in fact, an instance of ServiceIamUsing in the jar that is also Spring-annotated (#Component, #Service, etc.)? It's possible this is the case, but I'd like to clarify.
If not, does the jar expose a Spring context file you can import, thus adding the additional beans to your context for autowiring?
Related
How can the Class in a jar file get scanned by the <context:component-scan base-package="" />. I am getting the below error for my autowired class.
SEVERE [localhost-startStop-1] org.apache.catalina.core.ApplicationContext.log StandardWrapper.Throwable
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.quartz.Scheduler com.path.controller.MyController.scheduler; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.quartz.Scheduler] 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)}
code:
package com.path.controller;
import org.quartz.Scheduler;
#Controller
public class MyController{
#Autowired
Scheduler scheduler;
}
This scheduler is inside the jar file quartz-oracle-2.1.6.jar and is under WEB-INF\lib. This lib is outside the classes folder of the deployment package. In the applicationcontext.xml i have the below entry,
<context:component-scan base-package="com.path" />
When you export the jar file using the export utility in eclipse there is a option called Add directory entries. Check this option and export the jar file, this will solve the problem
I'm guessing you haven't defined your scheduler bean. You need to first define the bean in order to inject into your controller.
In your applicationcontext.xml first define a bean with type Scheduler.
You might need something like below. Be sure to check out the quartz documentation to check which scheduler you need and how to instantiate it.
<bean id="schedulerFactory"
class="org.quartz.StdSchedulerFactory" />
<bean id="scheduler" class="org.quartz.Scheduler" factory-bean="schedulerFactory" factory-method="getDefaultScheduler" />
As the exception complains "No qualifying bean of type [org.quartz.Scheduler]" , we will have to define the bean of type org.quartz.Scheduler, But that is not possible without any concrete implementation of the same, So , we will have to get a concrete implementation from the Factory class org.quartz.impl.StdSchedulerFactory and it's non static method getScheduler().
Hence, you will have to add following two lines in you context xml file and it will work , I have verified the same with the same version of spring which you are using :
<bean id="schedulerFactory" class="org.quartz.impl.StdSchedulerFactory" />
<bean id="scheduler" class="org.quartz.Scheduler" factory-bean="schedulerFactory" factory-method="getScheduler" />
A console output after printing the initialized bean gives this :
scheduler=org.quartz.impl.StdScheduler#536aaa8d
I have a service, which injects a Bean with #Autowired as follows.
#Service
public class AdminServiceImpl implements AdminService {
#Autowired
private WebServiceTemplate adminServiceTemplate;
}
And an xml that holds two beans, causing ambiguous autowiring
<bean id="serviceWebClient" class="org.springframework.ws.client.core.WebServiceTemplate" scope="prototype">
<constructor-arg ref="messageFactory" />
<property name="marshaller" ref="marshaller" />
<!-- More properties -->
</bean>
<bean id="adminServiceWebClient" class="org.springframework.ws.client.core.WebServiceTemplate" scope="prototype">
<constructor-arg ref="messageFactory" />
<property name="marshaller" ref="marshaller" />
<!-- More properties -->
</bean>
This obviously causes the following exception (at startup):
No qualifying bean of type [org.springframework.ws.client.core.WebServiceTemplate] is defined: expected single matching bean but found 2: serviceWebClient,adminServiceWebClient
The weird part:
When I add the #Qualifier in my service to specify which Bean to select, it suddenly can't find any anymore. E.g. I edit my service to the following:
#Service
public class AdminServiceImpl implements AdminService {
#Autowired
#Qualifier("adminServiceWebClient")
private WebServiceTemplate adminServiceTemplate;
}
And instead of getting my specified Bean, I get the following exception message (at a later time when I retrieve the ApplicationContext with context = new ClassPathXmlApplicationContext(CONFIG_FILE);):
No qualifying bean of type [org.springframework.ws.client.core.WebServiceTemplate] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.
Is there any logical explanation of something this odd happening? I'm not even sure where to start debugging. It seems to find both, but still refuses to autowire one.
Edit
When removing the additional Bean from my XML and the #Qualifier annotation, I still get:
No qualifying bean of type [org.springframework.ws.client.core.WebServiceTemplate] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.
But it works fine at startup. It just fails after calling:
context = new ClassPathXmlApplicationContext(CONFIG_FILE);
So at startup it seems to find it (it's required and doesn't fail), but it fails when requesting the context.
Perhaps you are actually starting two application contexts? One would have those beans present while the other wouldn't.
If this is the case, your first context would start okay when the qualifier is present but second one would fail due to the beans missing (exception #2). With no qualifier present, first context would fail to start due to two alternates.
To solve this (when starting second context) give it a parent context:
new ClassPathXmlApplicationContext(new String[]{CONFIG_LOCATION}, parentContext);
I have found out why this problem occurred. And it was a (rather stupid) mistake. In case someone else also runs into this, check out the following:
Overview
I run my application with various Spring Bean files. When my application starts, I use a "main context" file which does a component-scan of my entire base-package. Inside this "main" file I have the WebServiceTemplate Beans.
Startup
My component-scan finds my service and autowires its respectful WebServiceTemplate Bean into it. So it works fine at startup, as expected.
Runtime
When I call
context = new ClassPathXmlApplicationContext(CONFIG_FILE);
I actually call a different file. This file does not contain the WebServiceTemplate Beans but it did also contain a component-scan of the entire base-package. Causing it to find my Service, but not the beans it should autowire.
Solution
When loading the other file, I changed the component-scan to be more narrowed down to just what I need. So it doesn't scan for the service, but it gets loaded at startup.
I am trying to add a new Spring bean to one of my projects. The bean is defined and created in another package like so:
#Configuration
public class UtilityBeans {
public static String MY_BEAN_NAME = "my.bean.name";
#Bean(name = MY_BEAN_NAME)
public MyUtilBeanClass getMyBeanClass() {
return new MyUtilBeanClass();
}
}
I use it in my other package like this:
#Configuration
#Import({
UtilityBeans.class
)}
...
#Resource(name = UtilityBeans.MY_BEAN_NAME)
private MyUtilBeanClass myUtilBeans;
During runtime I get:
ERROR
Caused by: org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name 'my.bean.name': Singleton bean creation not allowed while the singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)
...
The logs do not give me any useful information as the stack trace is all in Spring library. How can I find out what failed? Is it incorrect usage of resource or is it that the bean creation itself is wrong?
I am using Spring-4 with JDK8.
The issue here was that the bean was being created in 2 different points in my spring configuration due to some refactoring and the fix was to remove duplicate code. I had the same bean creation code:
#Bean(name = MY_BEAN_NAME)
public MyUtilBeanClass getMyBeanClass() {
return new MyUtilBeanClass();
}
... in another class I had half way refactored.
In this case my mistake was that I did not grep across all the log files being generated. The exceptions were being split and then buried into 2 different logs, one for a server start up and one for application runtime. The above exception was being posted to the application log. The other logs contained the relevant exception which stated that duplicate bean creation failed and the fix was to remove duplicate code.
So i have a situation when I need to use spring integration. So I create application context for it and then i describe my all logic in it. But now, I have an error something like this:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [java.util.Properties] is defined: expected single matching bean but found 2: [integrationGlobalProperties, systemProperties]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:800)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:707)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1184)
... 61 more
Does someone faced with this problem with systemProperties and integrationGlobalProperties? What does it mean?
P.s. my application context is imported into another application context which has "default-autowire="byType"
As you see your context has two bean of java.util.Properties. That means that you can't inject byType.
Use #Qualifier("systemProperties") to restrict it to specific Properties.
The integrationGlobalProperties isn't only one bean which is populated by Framework. And it isn't a surprise that autowire byType is more and more bad for real applications.
I recently faced same issue. After some research I have decided to wirte a CustomBeanPostProcessor class (implementing BeanFactoryPostProcessor) which will try to find conflicting bean and change its 'autowire' property to 'byName', thus avoiding conflict.
Please have a look at a code below:
public class CustomBeanPostProcessor implements BeanFactoryPostProcessor{
#Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
if (beanFactory.containsBean("integrationGlobalProperties")){
//Choose on of the options - either disable autowiring for bean completly,
//or change autowiring type
beanFactory.getBeanDefinition("integrationGlobalProperties").setAutowireCandidate(false);
beanFactory.getBeanDefinition("integrationGlobalProperties").setAttribute("autowire", "byName");
}
}
}
Do not forget to declare this class as Spring bean as well:
<bean class="edu.stackoverflow.spring.misc.CustomBeanPostProcessor"/>
I'm currently just starting out with Spring and trying to get the hang of it. But I've run into a problem: My #Autowired keeps failing.
In my spring.xml I've got this:
<!--Handle #Autowired-->
<context:annotation-config />
<context:component-scan base-package="org.MYPROJECT">
<context:include-filter type="regex" expression=".*"/>
</context:component-scan>
When running some tests it fails with this (I'm only showing the last exception as its the most important)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.quackbot.dao.AdminDAO] 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.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:920)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:789)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:474)
... 50 more
So I try to fix it by adding the bean manually to the config
<bean id="AdminDAO" class="org.quackbot.dao.hibernate.AdminDAOHibernate">
</bean>
Run it again, now I get this
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [org.quackbot.dao.AdminDAO] is defined: expected single matching bean but found 2: [adminDAOHibernate, AdminDAO]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:796)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:474)
... 50 more
Seems I just can't win when using Spring... First it complains that the beans don't exist, when specifying them it complains that there's too many. What's going on? Why can't it load the correct beans?
Do you have an annotation in your dao?
Something like #Repository or #Component right above the class to tell Spring this needs to be picked up when scanning your base package?
This is more than enough, no other XML configuration is needed in your case:
<context:component-scan base-package="org.quackbot"/>
Secondly, make sure AdminDAOHibernate implements AdminDAO.
Last but not least, double check that the field annotated with #Autowired is of type AdminDAO (interface).
Last piece of advice: add default constructor to AdminDAOHibernate and place place some logging statement there or put breakpoint. There should be only one invocation of this constructor, although it gets tricky when class proxies are involved.
Is this a Spring MVC app? One way or another, I'm guessing you have two separate Spring contexts, whether you know it or not. In one context, you have a dependency on your AdminDAO, but it isn't available, which causes your first exception. Your other context also has a dependency on AdminDAO which is already satisfied, but when you manually add another AdminDAO bean, that fails because there are two of them.
#Autowired using annotations
#Repository("ExampleDao")
public class ExampleDaoImpl implements ExampleDao
#Service("ServiceExample")
public class ExampleServiceImpl implements ExampleService
#Controller
public class ExampleController
#Autowired
private ExmpleService ServiceExample;