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