6 Replies Latest reply on Apr 12, 2012 3:41 AM by luksa

    dynamic injection with beanmanager

    tomathome

      //

      //Qualifier Class

      //

      {code}

      @Qualifier

      @Documented

      @Retention(RetentionPolicy.RUNTIME)

      @Target({METHOD, FIELD, ElementType.TYPE, PARAMETER})

      public @interface Car {

        @Nonbinding

        String name() type "";

      }

      {code}

       

      //

      // Bean Class

      //

      {code}

      public class CarInst {

          private String test  = "initial";

       

          public CarInst(String name) {

              test = name;

          }

       

          public String getTest() {

              return test;

          }

      }

      {code}

       

      //

      //Producer Class

      //

      public class CarInstProducer {

          @Produces @Car()

          public CarInst produce(InjectionPoint ip) {

              for( Annotation qualifier : ip.getQualifiers() ) {

                  if( qualifier instanceof Car ) {

                      Car carType = (Car)qualifier;

                      return new CarInst(carType.type());

                  }

              }

              return null;

          }

      }

       

      //

      // Car literal class

      //

      public abstract class CarLiteral extends AnnotationLiteral<Car> implements Car {

        private static final long serialVersionUID = 742218573198647647L;

        public String type() {

          return "Value from Literal";

        }   

      }

       

       

       

       

      // Static Injection is working correctly.

      // The 'InjectionPoint ip' in producer class is not null,

      // so the type() can be retrieved from the ip.

      @Inject @Car(type="familly")

      CarInst carInst;

       

      // The test main method.

      // Try to inject CarInst dynamically by the use of beanmanager.

      // The producer method throw NullPointerException, because InjectionPoint is null.

      // the type() cannot be retieved from ip.

      main() {

        CarLiternal carLiteral  = new CarLiteral();

        Set<Bean<?>> beans = beanManager.getBeans(CarInst.class, carLiteral);

        Bean<?> bean = beans.iterator().next();

        CreationalContext<?> creationalContext = beanManager.createCreationalContext(bean);

       

        // The producer method will be executed here. NullPointer exception.

        getReference(bean, CarImpl.class, creationalContext);

      }

       

      Somebody know, how to use beanmanager to inject the CarImple dynamically and put somehow the type() dynamically,

      so that the producer method can retrieve it from InjectionPoint ip parameter?

        • 1. Re: dynamic injection with beanmanager
          luksa

          Can you paste the stacktrace of the NPE?

          • 2. Re: dynamic injection with beanmanager
            tomathome

            Exception in thread "main" java.lang.NullPointerException

                at CarInstProducer.produce(CarInstProducer.java:36)

                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

                at java.lang.reflect.Method.invoke(Method.java:601)

                at org.jboss.weld.util.reflection.SecureReflections$13.work(SecureReflections.java:264)

                at org.jboss.weld.util.reflection.SecureReflectionAccess.run(SecureReflectionAccess.java:52)

                at org.jboss.weld.util.reflection.SecureReflectionAccess.runAsInvocation(SecureReflectionAccess.java:137)

                at org.jboss.weld.util.reflection.SecureReflections.invoke(SecureReflections.java:260)

                at org.jboss.weld.introspector.jlr.WeldMethodImpl.invokeOnInstance(WeldMethodImpl.java:170)

                at org.jboss.weld.injection.MethodInjectionPoint.invokeOnInstance(MethodInjectionPoint.java:137)

                at org.jboss.weld.bean.ProducerMethod$1.produce(ProducerMethod.java:133)

                at org.jboss.weld.bean.AbstractProducerBean.create(AbstractProducerBean.java:299)

                at org.jboss.weld.context.unbound.DependentContextImpl.get(DependentContextImpl.java:61)

                at org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:616)

                at org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:643)

                at Main.test(Main.java:74)

                at Main.main(Main.java:58)

            • 3. Re: dynamic injection with beanmanager
              luksa

              Ah, yes, of course. Your producer is called with null InjectionPoint, because there is no injection point. (Weld should probably throw its own exception here. something along the lines of "Cannot inject InjectionPoint into producer method xxx").

               

              Maybe you could try calling beanManager.getInjectableReference(InjectionPoint, CreationalContext)?

              • 4. Re: dynamic injection with beanmanager
                luksa

                Oh, and you also need to change your CarLiteral to something like this:

                 

                public class CarLiteral extends AnnotationLiteral<Car> implements Car {

                    private static final long serialVersionUID = 742218573198647647L;

                 

                    private String type;

                 

                    public CarLiteral(String type) {

                        this.type = type;

                    }

                 

                    public String type() {

                        return type;

                    }

                }

                • 5. Re: dynamic injection with beanmanager
                  tomathome

                  If i use beanManager.getInjectableReference, then I need to create the InjectionPoint Instance for selfe? Also something like

                   

                  public Class CarExtentionPoint implements ExtentionPoint {

                  ...

                  }

                   

                  beanmanager.getInjectableReference(new CarExtentionPoint(...), creationalContext);

                  ???

                   

                  I check which Methods i need to overwrite  for the new InjectionPoint Class...

                   

                  The Literal give the static value only for test. You have right, that the value should be given by the constructor parameter. But it doesn't couse the NullPointer Exception in producer, isn't it?

                   

                   

                  Many Thanks

                  • 6. Re: dynamic injection with beanmanager
                    luksa

                    Yes, you need to create an InjectionPoint instance, otherwise there won't be any InjectionPoint that can be injected into your producer method.

                     

                    tomathome wrote:

                     

                    The Literal give the static value only for test. You have right, that the value should be given by the constructor parameter. But it doesn't couse the NullPointer Exception in producer, isn't it?

                     

                    You are correct - that's not the cause of the NPE. The cause of the NPE is that there is no injection point if the producer method is called as a result of calling beanManager.getReference().