Uploaded image for project: 'Application Server 7'
  1. Application Server 7
  2. AS7-4159

Double-checked locking in org.jboss.weld.util.BeansClosure#getClosure is a cause for NPE

XMLWordPrintable

      Application deployment fails with a following exception:

      05:33:26,201 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-7) MSC00001: Failed to start service jboss.deployment.unit."exp-cdi-injectApplication.war".WeldService: org.jboss.msc.service.StartException in service jboss.deployment.unit."exp-cdi-injectApplication.war".WeldService: java.lang.NullPointerException
      at org.jboss.as.weld.services.WeldService.start(WeldService.java:83)
      at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
      at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
      at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [rt.jar:1.6.0_27]
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [rt.jar:1.6.0_27]
      at java.lang.Thread.run(Thread.java:662) [rt.jar:1.6.0_27]
      Caused by: java.lang.NullPointerException
      at org.jboss.weld.bootstrap.BeanDeployment.createBeans(BeanDeployment.java:194)
      at org.jboss.weld.bootstrap.WeldBootstrap.deployBeans(WeldBootstrap.java:336)
      at org.jboss.as.weld.WeldContainer.start(WeldContainer.java:82)
      at org.jboss.as.weld.services.WeldService.start(WeldService.java:76)
      ... 5 more

      Looking at the code that belongs to weld-core-1.1.5.AS71.Final, we can see the following at the lines 193-194 of BeanDeployment:

      193: BeansClosure closure = BeansClosure.getClosure(this.beanManager);
      194: closure.addEnvironment(this.beanDeployer.getEnvironment());

      Which leads to a conclusion that closure is null (the lines prior to the mentioned ones show that beanDeployer itself couldn't be null).
      Looking into BeansClosure#getClosure():

      public static BeansClosure getClosure(BeanManagerImpl beanManager)
      {
      BeansClosure closure = (BeansClosure)closureMap.get(beanManager);
      if (closure == null) {
      synchronized (closureMap) {
      if (!closureMap.containsKey(beanManager)) {
      closure = new BeansClosure();
      for (Iterable beanManagers : BeanManagers.getAccessibleClosure(beanManager)) {
      for (BeanManagerImpl accessibleBeanManager : beanManagers)

      { closureMap.put(accessibleBeanManager, closure); }

      }
      }
      }
      }
      return closure;
      }

      To prevent race conditions, maybe it makes sense to reside the full method body into synchronized block.

              sdouglas1@redhat.com Stuart Douglas (Inactive)
              arhan_jira Anton Arhipov (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Created:
                Updated:
                Resolved: