5 Replies Latest reply on Aug 24, 2016 5:49 AM by brucespringfield

    WELD-000049: Unable to invoke void com.mydomain.bc.alert.AService.init() Caused by java.lang.NullPointerException

    brucespringfield

      Trying to inject dependencies into a Junit test with Weld. But Weld is getting a NullPointer Exception 

       

      Caused by: java.lang.reflect.InvocationTargetException

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

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

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

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

        at org.jboss.weld.injection.producer.DefaultLifecycleCallbackInvoker.invokeMethods(DefaultLifecycleCallbackInvoker.java:98)

        ... 51 more

      Caused by: java.lang.NullPointerException

        at com.mydomain.bc.configuration.facade.AConfigurationFacadeImpl.getInputContactOfMyD(AConfigurationFacadeImpl.java:36)

        at com.mydomain.bc.alert.AService.initAContactCache(AService.java:87)

        at com.mydomain.bc.alert.AService.init(AService.java:83)

        ... 56 more

       

      It seems Weld has a problem injecting the nested dependency of the first dependency.

       

      Is there a workaround for this problem?

       

      1)

      @Singleton

      @LocalBean

      public class OuterEventObserverBCAC extends OuterEventObserver {

       

      .

      .

      .


      @Inject

      private AService aService;

      }

       

      2)

      @Singleton

      @Startup

      @LocalBean

      public class AService {

       

      .

      .

      .

       

      @Inject

      private ACRepository acRepository;

      }

       

      3)

      @ApplicationScoped

      @Singleton

      public class ACRepository extends RRepositoryImpl<AContact> {

      .

      .

      .

      4)

          @Inject

          @AContactCache

          private RCache<String, AContact> alCCache;

      }

        • 1. Re: WELD-000049: Unable to invoke void com.mydomain.bc.alert.AService.init() Caused by java.lang.NullPointerException
          mkouba

          Bruce, it seems the NullPointerException is thrown from the application code: com.mydomain.bc.configuration.facade.AConfigurationFacadeImpl.getInputContactOfMyD(AConfigurationFacadeImpl.java:36)

          • 2. Re: WELD-000049: Unable to invoke void com.mydomain.bc.alert.AService.init() Caused by java.lang.NullPointerException
            brucespringfield

            Yes, but the Exception only occurs when I try to inject dependencies into the test with Weld. If I don't do this, this Exception doesn't occur.

            • 3. Re: WELD-000049: Unable to invoke void com.mydomain.bc.alert.AService.init() Caused by java.lang.NullPointerException
              mkouba

              I'm afraid we can't help you without a deeper knowledge of the source code. E.g. it's very important to know what's on the line AConfigurationFacadeImpl.java:36.

              • 4. Re: WELD-000049: Unable to invoke void com.mydomain.bc.alert.AService.init() Caused by java.lang.NullPointerException
                brucespringfield

                On line 36 of AConfigurationFacadeImpl:


                return configurationService.getMsr().getMsrD().stream() //

                .filter(dep -> isDOfNtip(dep))//

                .flatMap(asStream(MsrD::getMsrAudioFv)) //

                .flatMap(asStream(MsrAudioFv::getMsrInputContact));

                 

                It seems the injected Bean is not using configurationService.


                The injected bean is:

                OuterEventObserverBCAC


                It is being injected into the test through:


                private static void initializeCdiDependencies() {


                  cdiContainer = CdiContainer.getInstance();

                  cdiContainer.initializeCdiContainer();


                  outerEventObserverBCAC = cdiContainer.getBean(outerEventObserverBCAC.class);

                  cdiContainer.shutdownCdiContainer();

                }


                The error starts at the line:


                  outerEventObserverBCAC = cdiContainer.getBean(outerEventObserverBCAC.class);


                configurationService is not injected. Should it be injected also?

                 

                 

                My cdiContainder code:

                 

                public final class CdiContainer {

                    private static final CdiContainer INSTANCE = new CdiContainer();


                    /** The logger for CdiContainer. */

                    // private final static Logger LOG = LogManager.getLogger(CdiContainer.class);

                 

                    /**

                    * Get the current instance of the CdiContainer to obtain managed beans.

                    *

                    * @return the {@link CdiContainer}.

                    */

                    public static final CdiContainer getInstance() {

                      return INSTANCE;

                    }

                 

                    /**

                    * Constructor.

                    */

                    private CdiContainer() {

                    }

                 

                 

                    /**

                    * Obtain the managed bean of the provided type from the CDI container.

                    *

                    * @param clazz

                    *            the type of the bean to get from the CDI container.

                    * @param qualifiers

                    *            the qualifiers for the bean selection to resolve ambiguous beans.

                    * @return the managed bean instance.

                    */

                    public <T> T getBean(final Class<T> clazz, final Annotation... qualifiers) {

                          return weldContainer.select(clazz, qualifiers).get();

                    }

                 

                    /**

                    * Initialize the CDI container. Must be only called once during application startup.

                    */

                    public void initializeCdiContainer() {

                 

                      if (weldContainer == null) {

                          // LOG.debug("Initializing CDI implementation JBoss Weld");

                          // Initialize the CDI reference implementation JBoss WELD to bootstrap CDI and get access to managed beans

                          final Weld weld = new Weld();

                          weldContainer = weld.initialize();

                      } else {

                          // LOG.debug("JBoss Weld already initialized");

                      }

                  }


                  public void shutdownCdiContainer() {

                      if (weldContainer != null) {

                        weldContainer.shutdown();

                      }

                  }


                    /** The weld container controlling the life cycle of all CDI managed beans. */

                    public WeldContainer weldContainer;

                }

                • 5. Re: WELD-000049: Unable to invoke void com.mydomain.bc.alert.AService.init() Caused by java.lang.NullPointerException
                  brucespringfield

                  The solution was not to inject dependencies into a Junit test with Weld. I was trying to use the WeldContainer to inject the dependencies. But there were too many nested and complex dependencies to make it realistic. I kept getting NullPointer Exceptions everywhere. So instead of using Weld and the WeldContainer, I scrapped it and used CdiRunner to run the Junit test. CdiRunner works very well injecting dependencies. It was important to use the @AdditionalClasses and @ActivatedAlternatives annotations to let CdiRunner know which classes needed to be injected. One trick was to add the test class itself into the @ActivatedAlternatives annotation.


                  Here is a sample:


                  @Alternative

                  @RunWith(CdiRunner.class)

                  @AdditionalClasses({ ACFacadeImpl.class })

                   

                  @ActivatedAlternatives({ ACServiceNonArqBCT.class, MshoEventObserverBcACFake.class })

                  public class ACServiceNonArqBCT {

                  .

                  .

                  .