Instance interface, @New qualifier
marekm Dec 17, 2011 11:54 AMI have a bean InjectionOnDemand (IOD) which injects beans/services programmatically through Instance interface. Target bean types/names are resolved during runtime.
I would like to enforce two approaches in my IOD.
First is to obtain an existing instance of bean without modifing its scope.
I do it that way:
In my IOD
@Inject @Any private Instance<Object> anyObject;
In IOD method
Set<Bean<?>> set = beanManager.getBeans(key.toString()); if (set.isEmpty()){ // TODO exception }else{ Bean<?> bean = set.iterator().next(); Class<?> clazz = bean.getBeanClass(); try { Object obj = anyObject.select(clazz).get(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
And it works fine. I have a proxy to the object which has its normal scope
The second approach is to obtain always new instance of bean ignoring target bean scope. I assume that target bean will become Dependent with all dependencies injected into it. For the same type of bean as above I get Exception
@Inject @New private Instance<Object> dataModelObject;
Set<Bean<?>> set = beanManager.getBeans(key.toString()); if (set.isEmpty()){ // exception }else{ Bean<?> bean = set.iterator().next(); Class<?> clazz = bean.getBeanClass(); System.out.println("Class to inject: "+clazz); System.out.println(bean.getStereotypes()); System.out.println(bean.getTypes()); System.out.println(bean.getQualifiers()); System.out.println(bean.getScope()); try { Object obj = dataModelObject.select(clazz).get(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
And I get UnsatisfiedResolutionException.
INFO: Class to inject: class easywebflow.sample.User INFO: [interface javax.enterprise.inject.Model] INFO: [class java.lang.Object, class easywebflow.sample.User, interface java.io.Serializable] INFO: [@javax.enterprise.inject.Any(), @javax.enterprise.inject.Default()] INFO: interface javax.enterprise.context.RequestScoped WARNING: #{newUser.start}: org.jboss.weld.exceptions.WeldException: WELD-000049 Unable to invoke [method] @PostConstruct public easywebflow.core.FlowImpl.initializeFlowContext() on easywebflow.core.FlowImpl@9a9807 javax.faces.FacesException: #{newUser.start}: org.jboss.weld.exceptions.WeldException: WELD-000049 Unable to invoke [method] @PostConstruct public easywebflow.core.FlowImpl.initializeFlowContext() on easywebflow.core.FlowImpl@9a9807 at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118) (...) Caused by: org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001308 Unable to resolve any beans for Types: [class easywebflow.sample.User]; Bindings: [@javax.enterprise.inject.New(value=easywebflow.sample.User.class)] at org.jboss.weld.manager.BeanManagerImpl.getBean(BeanManagerImpl.java:809) at org.jboss.weld.bean.builtin.InstanceImpl.get(InstanceImpl.java:108) at easywebflow.core.InjectionOnDemandMap.injectModel(InjectionOnDemandMap.java:91) at easywebflow.core.InjectionOnDemandMap.get(InjectionOnDemandMap.java:67) at easywebflow.core.InjectionOnDemandMap.injectDataModel(InjectionOnDemandMap.java:55) at easywebflow.core.FlowImpl.initializeFlowContext(FlowImpl.java:95) ... 58 more
So annotating Instance with @New qualifier somehow results in UnsatisfiedResolutionException be thrown.
I also tried to add all qualifiers of the bean to the select method. Then i get simmilarly this:
Caused by: org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001308 Unable to resolve any beans for Types: [class easywebflow.sample.User]; Bindings: [@javax.enterprise.inject.Default(), @javax.enterprise.inject.Any(), @javax.enterprise.inject.New(value=easywebflow.sample.User.class)] at org.jboss.weld.manager.BeanManagerImpl.getBean(BeanManagerImpl.java:809) at org.jboss.weld.bean.builtin.InstanceImpl.get(InstanceImpl.java:108) at easywebflow.core.InjectionOnDemandMap.injectModel(InjectionOnDemandMap.java:92) at easywebflow.core.InjectionOnDemandMap.get(InjectionOnDemandMap.java:67) at easywebflow.core.InjectionOnDemandMap.injectDataModel(InjectionOnDemandMap.java:55) at easywebflow.core.FlowImpl.initializeFlowContext(FlowImpl.java:95) ... 58 more
Could anyone tell me what is wrong ? Maybe @New qualifier isn't what I espected him to be. How to leverege Instance interface to get always new object with dependent scope? To be clear, I cannot use new operator becouse injected services may have injected fields. I want to fully use CDI mechanism.
Regards
Marek