I am trying to insert a Jersey 2.7 resource withing a Spring managed bean. Specifically, I want to inject OAuth1Signature within a Spring bean like so:
#Component
public class OAuthManager {
#Inject
private OAuth1Signature oAuthSignature;
private void someMethod() {
String signature = oAuthSignature.generate(oauthRequest, params, secrets);
}
}
I have tried using instructions provided within the HK2 Spring integration document: HK2 Spring Integration. Following the document, I added this to my spring xml configuration:
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="hk2">
<bean class="org.jvnet.hk2.spring.bridge.api.SpringScopeImpl" >
<property name="ServiceLocatorName" value="HK2ToSpringTest" />
</bean>
</entry>
</map>
</property>
</bean>
<bean id="org.glassfish.jersey.oauth1.signature.OAuth1Signature"
class="org.glassfish.jersey.oauth1.signature.OAuth1Signature"
scope="hk2"
lazy-init="true" />
However, I keep getting this exception when I start my webapp:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.glassfish.hk2.api.ServiceLocator] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:952)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:821)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:735)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:795)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:723)
OAuth1Signature documentation states that the ServiceLocator is supposed to be injected by HK2 framework which Jersey 2.7 uses. I am very confused on how I can get Spring to instantiate OAuth1Signature for me using the jersey-spring3 bridge since it does not seem to know where the Service locator should come from.
I have tried searching through StackOverflow and other Jersey message boards, but most of them deal with the opposite use case (injecting spring beans in a Jersey resource). Any help on this would be greatly appreciated !
I have recently done the development for OAuth in my project where I used Jersey 2.9.1 with Spring.
Below is what needs to be done to autowire the "OAuth1Signature's" instance in the Spring as we require hk2 to spring bridge to inject the hk2 services in the spring.
1.Define the custom hk2 scope
#Bean
public static CustomScopeConfigurer scopeConfigurer() {
Map<String, Object> scopeMap = new HashMap<String, Object>();
SpringScopeImpl hk2SpringScope = new SpringScopeImpl();
CustomScopeConfigurer customScopeConfigurer = new CustomScopeConfigurer();
hk2SpringScope.setServiceLocatorName("hk2SpringLocator");
scopeMap.put("hk2", hk2SpringScope);
customScopeConfigurer.setScopes(scopeMap);
return customScopeConfigurer;
}
2.Define the OAuth1Signature bean in "hk2" scope
#Bean(name = "oauth1Signature")
#Scope("hk2")
public OAuth1Signature getOAuth1Signature() {
ServiceLocator hk2ServiceLocator = ServiceLocatorFactory.getInstance()
.find("hk2SpringLocator");
OAuth1Signature oAuth1Signature = new OAuth1Signature(hk2ServiceLocator);
return oAuth1Signature;
}
3.After you are done with above 2 steps, you are ready to the autowire the "OAuth1Signature".
#Autowired
private OAuth1Signature oAuth1Signature;
Cheers
Related
Hii iam doing spring ORM with hibernate. while running the program iam getting bellow error.. iam giving all my config,pojo,daos please check
WARNING: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'vehicleDao': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.orm.hibernate3.HibernateTemplate in.JavaHome.SpringHiber.DAO.vehicleDao.template; nested exception is java.lang.NoClassDefFoundError: [Lorg/hibernate/engine/FilterDefinition;
Exception in thread "main" java.lang.NoSuchMethodError: org.springframework.util.ReflectionUtils.clearCache()V
at org.springframework.context.support.AbstractApplicationContext.resetCommonCaches(AbstractApplicationContext.java:879)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:563)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at addVehicle.main(addVehicle.java:11)
Configuration spring is..
<context:component-scan base-package="in.JavaHome.SpringHiber"></context:component-scan>
<bean name="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocations" value="classpath:hibernate.cfg.xml"></property>
</bean>
<bean name="hibTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean name="hibTransManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<tx:annotation-driven transaction-manager="hibTransManager"/>
Dao Class
#Component
public class vehicleDao {
#Autowired
private HibernateTemplate template;
#Transactional
public void addVehicle(vehicle v){
template.save(v);
}
main.java
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext contex= new ClassPathXmlApplicationContext("config.xml");
vehicleDao dao = (vehicleDao) contex.getBean("vehicleDao.class");
vehicle v=new vehicle();
v.setName("S cross");
v.setCost(1500000);
dao.addVehicle(v);
}
Iam new to spring mvc so, please tell me the whr the problem.
Thank u
If my guess is correct, you are following a Tutorial to learn about Spring. If so, congratulations and good luck, Spring is a very powerful framework! Though it appears that you are using a very old tutorial - I'd suggest looking for a more modern spring tutorial example as XML configuration (as well as Hibernate 3) are not modern approach. Perhaps something from: http://spring.io/guides
but for this specific problem it seems likely that you have incompatible jars on your classpath. If you plan to use hibernate 3 you need to ensure it's on the classpath and that you are not using a modern version of spring either. See: compatability of spring 4.0.0 with hibernate 4.30
The problem is you defined bean in xml like this
<bean name="hibTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
but your using template to autowire the bean name should be same or use #Qualifier
#Autowired
private HibernateTemplate template;
change this to
#Autowired
private HibernateTemplate hibTemplate;
or
#Autowired
#Qualifier("hibTemplate")
private HibernateTemplate hibTemplate;
I'm currently using Spring 3 annotations along with hibernate 3 for the database connectivity. I also have to be using spring tiles.
My spring-servlet.xml is:
<context:annotation-config />
<context:component-scan base-package="com.xxx.controller,com.xxx.dao,com.xxx.service" />
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver"
id="viewResolver">
<property name="viewClass">
<value>
org.springframework.web.servlet.view.tiles2.TilesView
</value>
</property>
</bean>
<bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer"
id="tilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/plugin/impl/tiles/springtiles-defs.xml</value>
</list>
</property>
</bean>
//Is this required????
<!-- <bean id="MyDAO" class="com.xxxx.MyDAOImpl"></bean>
<bean id="MyService" class="com.xxxx.MyServiceImpl"></bean> -->
My controller class :
#Controller
public class myController {
#Autowired
private MyService myService;
public myController() {
}
#RequestMapping(value="/index.do", method = RequestMethod.GET)
protected ModelAndView Submit(HttpServletRequest request, HttpServletResponse response) throws Exception {
// TODO Auto-generated method stubs
System.out.println(" Inside the controller ");
</beans>
And my serviceImpl class:
#Service("MyService")
public class MyServiceImpl implements MyService{
#Autowired
MyDAO myDAO;
And my DaoImpl class :
#Repository/*("myDAO")*/
public class MyDAOImpl implements MyDAO{
List<String> clientList;
#Autowired
private SessionFactory sessionFactory;
private Session session;
private Session currentSession() {
return this.sessionFactory.getCurrentSession();
}
#Override
public List<ClientInfoBean> getClientList(String currentQrt) throws DataStoreException {
// TODO Auto-generated method stub
return (List<ClientInfoBean>) this.currentSession().
createCriteria("Select * from myTable);
}
It still gives the below exceptions.
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: private com.xxx.service.MyService com.xxx.controller.MyController.MyService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.xxx.service.MyService] 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.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1116)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.xxx.service.MyService com.xxx.controller.MyController.MyService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.xxx.service.MyService] 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:514)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
... 97 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.xxx.service.MyService] 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:988)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:858)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:770)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486)
... 99 more
So the problem is your packages:
You have definition of services and daos in: com.xxx.service and com.xxx.dao
and your implementation in: com.xxx.serviceImpl and com.xxx.daoImpl.
Add in also <context:component-scan base-package="com.xxx.serviceImpl,com.xxx.daoImpl"/>
Next problem you are facing is transactional management:
You havent defined it in spring configuration. This is an example how to do this:
<!-- Hibernate 3 Annotation SessionFactory Bean definition-->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.jdbc.batch_size">${batchSize}</prop>
</props>
</property>
</bean>
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
And after this you need to mark a method or your service implementation as #Transactional to make spring care of this.
The exception is clearly telling you that the bean is not configured
NoSuchBeanDefinitionException: No qualifying bean of type [com.xxx.service.MyService]
Can you check the case of the bean names that you given in annotations are matching with the parameter name. myService vs MyService.
Also adding a setter might be a good idea as spring can call setter to inject the dependency instead of using Reflection to inject it.
When you define
#Service("MyService")
public class MyServiceImpl implements MyService{
}
or
#Repository("MyDAO")
public class MyDAOImpl implements MyDAO{
}
you are actually telling spring to create bean with the name "MyService" & "MyDAO"
when you define like
#Autowired
private MyService myService;
#Autowired
private MyDAO myDAO;
you are asking from spring to give bean(s) with the name "myService" & "myDAO".
Since spring creates bean with the name which is different from what are you asking, it is giving the error.
You have to keep name of the bean in the #Service & #Repository annotation same as the variable name for the Interface.
#Service("myService")
public class MyServiceImpl implements MyService{
}
private MyService myService;
As you qualified your service as "MyService" , you can add qualifier as below to find it. By default spring should autowire by type , so component scan should load your service. If you are defining beans partially in xml and expecting other services to be autowired, you have to add in your spring-servlet.xml
#Autowired
#Qualifier("MyService")
private MyService myService;
Also change your controller class as MyController instead of myController.
And remove the constructor myController(), spring will construct for you controller bean. Try to remove all your constructors in all your spring bean classes, spring will construct for you. For the beginning you can avoid qualifying the beans, remove the names in brackets( "MyService", "MyDao" etc....)
Use
#Service
public class MyServiceImpl implements MyService
Instead of
#Service("MyService")
public class MyServiceImpl implements MyService{
I'm working on a code where a class A is constructing an object of class B using parameterized constructor of class B. As of now, class B is not yet spring injected. The requirement is that I should always have a new non-singleton object of class B. The code somewhat looks like this:
class A{
private List<ClassB> classBList = new ArrayList<ClassB>();
void parseInfo(File f, Element e){
ClassB b = new ClassB(this,f,e);
classBList.add(b);
}
}
How should my spring-config look like if i have to inject class B using spring?
Define the bean as prototype
<!-- A bean definition with singleton scope -->
<bean id="classBBean" class="ClassB" scope="prototype"/>
Use applicationContext getBean method to create bean each time by passing arguments.
class A implements ApplicationContextAware{
private List<ClassB> classBList = new ArrayList<ClassB>();
#Autowired
private ApplicationContext appContext;
void parseInfo(File f, Element e){
ClassB b = (ClassB)appContext.getBean("classBBean",new Object[]{this,f,e});
classBList.add(b);
}
}
If I understand correctly, you are asking about Spring scopes
Basically, you need to declare your bean with scope prototype if it's a general spring application
<!-- A bean definition with singleton scope -->
<bean id="..." class="..." scope="prototype">
<!-- collaborators and configuration for this bean go here -->
</bean>
or request, if it's a web spring application
<!-- A bean definition with singleton scope -->
<bean id="..." class="..." scope="request">
<!-- collaborators and configuration for this bean go here -->
</bean>
For more examples look at
http://www.tutorialspoint.com/spring/spring_bean_scopes.htm
I have 2 maven projects, a web-app, and a 'service' project. I am using spring to wire everything together. I would like to create a map in my application-context.xml, and have that injected into my class. When I try to start my web application I get an error message.
Here is my class:
#Named("tranformer")
public class IdentifierTransformerImpl implements IdentifierTransformer {
private Map<String, String> identifierMap;
#Inject
public IdentifierTransformerImpl(
#Named("identifierMap")
final Map<String, String> identifierMap) {
this.identifierMap= identifierMap;
}
and the application-context.xml:
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd"
<util:map id="identifierMap" map-class="java.util.HashMap">
<entry key="Apple" value="fruit"/>
<entry key="BlackBerry" value="fruit"/>
<entry key="Android" value="robot"/>
<util:map>
<context:component-scan base-package="com.example" />
I get the following error:
..... No matching bean of type [java.lang.String] found for dependency [map with value type java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#javax.inject.Named(value=identifierMap)
This works when I define a string in my application-context, and constructor inject it into a class, how can I do the same for a map?
I think Map collection is not supported by #Inject or #Autowired annotation (see: Spring can't autowire Map bean). However I managed to autowire a Map by annotating it as a resource as suggested by that answer. Try this:
#Resource(name="identifierMap") private Map<String, String> identifierMap;
The downside is ofcourse that isn't a constructor autowiring, but a field. I haven't found a way of doing it through constructor autowiring yet
If that is a direct copy/paste of your xml file, you aren't ending your <util:map> tag. You're missing a / in the second one.
With constructor injection.
#Inject
public IdentifierTransformerImpl(
#Value(value = "#{identifierMap}")
final Map<String, String> identifierMap) {
this.identifierMap= identifierMap;
}
Not ideal but Spring declines to provide a better option.
Check out more details at https://jira.spring.io/browse/SPR-8519
I can do this in my applicationContext with Spring (3.0.5):
<bean id="map" class="java.util.HashMap" scope="prototype" >
<constructor-arg>
<map key-type="java.lang.String" value-type="java.lang.String">
<entry key="Key 1" value="1" />
<entry key="Key 2" value="2" />
</map>
</constructor-arg>
</bean>
And in my controller, I can autowired my map like this:
#Autowired
#Qualifier("map")
private HashMap<String, String> map;
It works fine, but if I do this:
#Autowired
#Qualifier("map")
private Map<String, String> map;
I get that:
Caused by:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
matching bean of type [java.lang.String] found for dependency [map
with value type java.lang.String]: 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=map)}
My question is: Why I can't autowired my map with the interface when I can with the implementation ?
Thanks.
While declaring a bean of type collection, one cannot inject it via #Autowired. See below documentation from Spring:
4.11.3 Fine-tuning annotation-based autowiring with qualifiers
As a specific consequence of this semantic difference, beans which are
themselves defined as a collection or map type cannot be injected via
#Autowired since type matching is not properly applicable to them. Use
#Resource for such beans, referring to the specific collection/map
bean by unique name.
Thus instead of #Autowired, use #Resource:
#Resource
#Qualifier("map")
private Map<String, String> map;
Try to use #Resource instead of #Autowired
#Resource(name="map")
private HashMap<String, String> map;
Check out the tip in 3.9.3 Fine-tuning annotation-based autowiring with qualifiers of Spring's documentation