title: Why is there a WELD-001408 even when the BeanManager knows the EJB
body: <p>When trying to deploy an ear we get the infamous WELD-001408 (see below for stacktrace).</p>
  
  <p><em>Problem: It seems that WELD can't inject an EJB via @Inject into a CDI managed bean (!= @ManagedBean) in a lib/shared.jar.</em>
  Why is this? Is there a standard that says this is not supposed work?</p>
  
  <p><strong>UPDATE</strong>
  I also had an ejb-jar.xml at the relevant location...</p>
  
  <p><strong>UPDATE2:</strong>
  I created a minimal versin on <a href="https://github.com/bseiller/stackoverflow-34065368" rel="noreferrer">github</a></p>
  
  <p><strong>First the setup - my research/findings and more detailed questions at the end:</strong></p>
  
  <p>We are currently using Glassfish 4.1 => Weld 2.2.2.Final, but the error is the same using Payara 4.1.1.154 => Weld 2.2.16.Final, also Java EE 7</p>
  
  <p><strong>Layout of the ear</strong></p>
  
  <pre><code>sample.ear
  ├── a-ejb.jar (contains AEjb.java + beans.xml + ejb-jar.xml)
  ├── b-ejb.jar (contains AnotherCdiIManagedBeanPojo.java + DummyEjb.java + beans.xml)
  ├── lib
  |   └── shared.jar (contains ACdiManagedBeanPojo.java, AnotherCdiDependency.java + beans.xml)
  └── META-INF
      └── application.xml (...)
  </code></pre>
  
  <p>In the shared.jar there is </p>
  
  <pre><code>public class ACdiManagedBeanPojo {
      @Inject
      private AEjb aEjb;
  
      @Inject
      private AnotherCdiDependency anotherCdiDependency;        
  }
  </code></pre>
  
  <p>AEjb is an EJB residing in the a-ejb.jar </p>
  
  <pre><code>@javax.ejb.Singleton
  @javax.ejb.LocalBean
  @javax.enterprise.context.ApplicationScoped
  public class AEjb {}
  </code></pre>
  
  <p>AnotherCdiDependency is another Pojo in the shared.jar</p>
  
  <pre><code>public class AnotherCdiDependency {}
  </code></pre>
  
  <p>The following class resides in b-ejb.jar</p>
  
  <pre><code>public class AnotherCdiManagedBeanPojo {
      @Inject
      private AEjb aEjb;
  }
  </code></pre>
  
  <p><strong>beans.xml (CDI 1.1)</strong></p>
  
  <pre><code>&lt;beans bean-discovery-mode="all"
     xmlns="http://xmlns.jcp.org/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"&gt;
  &lt;/beans&gt;
  </code></pre>
  
  <p><strong>ejb-jar.xml</strong></p>
  
  <pre><code>&lt;ejb-jar xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd"
           version="3.1"&gt;
      &lt;enterprise-beans&gt;   
          &lt;session&gt;
              &lt;ejb-name&gt;AEjb&lt;/ejb-name&gt;
              &lt;ejb-class&gt;com.xxx.ejb.AEjb&lt;/ejb-class&gt;
              &lt;session-type&gt;Singleton&lt;/session-type&gt;
          &lt;/session&gt;
      &lt;/enterprise-beans&gt;
  &lt;/ejb-jar&gt;
  </code></pre>
  
  <p><strong>stacktrace</strong></p>
  
  <pre><code>org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type AEjb with qualifiers @Default
    at injection point [BackedAnnotatedField] @Inject @Default private com.managed.pojo.ACdiManagedBeanPojo.aEjb
    at com.managed.pojo.ACdiManagedBeanPojo.aEjb(ACdiManagedBeanPojo.java:0)
  
      at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:370)
      at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:291)
      at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:134)
      at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:165)
      at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:529)
      at org.jboss.weld.bootstrap.Validator.validateBeans(Validator.java:515)
      at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:490)
      at org.jboss.weld.bootstrap.WeldStartup.validateBeans(WeldStartup.java:419)
      at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:90)
      at org.glassfish.weld.WeldDeployer.event(WeldDeployer.java:225)
      at org.glassfish.kernel.event.EventsImpl.send(EventsImpl.java:131)
      at org.glassfish.internal.data.ApplicationInfo.load(ApplicationInfo.java:328)
      at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:496)
      at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:219)
      at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:491)
      at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:539)
      at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:535)
      at java.security.AccessController.doPrivileged(Native Method)
      at javax.security.auth.Subject.doAs(Subject.java:360)
      at com.sun.enterprise.v3.admin.CommandRunnerImpl$2.execute(CommandRunnerImpl.java:534)
      at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:565)
      at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:557)
      at java.security.AccessController.doPrivileged(Native Method)
      at javax.security.auth.Subject.doAs(Subject.java:360)
      at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:556)
      at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1464)
      at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1300(CommandRunnerImpl.java:109)
      at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1846)
      at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1722)
      at org.glassfish.admin.rest.utils.ResourceUtil.runCommand(ResourceUtil.java:253)
      at org.glassfish.admin.rest.utils.ResourceUtil.runCommand(ResourceUtil.java:231)
      at org.glassfish.admin.rest.utils.ResourceUtil.runCommand(ResourceUtil.java:275)
      at org.glassfish.admin.rest.resources.TemplateListOfResource.createResource(TemplateListOfResource.java:133)
      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.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
      at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:151)
      at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:171)
      at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:152)
      at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:104)
      at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:387)
      at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:331)
      at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:103)
      at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:271)
      at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
      at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
      at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
      at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
      at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
      at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:297)
      at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:254)
      at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1028)
      at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:365)
      at org.glassfish.admin.rest.adapter.RestAdapter$2.service(RestAdapter.java:316)
      at org.glassfish.admin.rest.adapter.RestAdapter.service(RestAdapter.java:179)
      at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
      at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
      at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201)
      at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175)
      at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
      at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
      at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
      at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
      at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
      at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
      at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
      at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
      at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
      at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
      at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
      at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
      at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
      at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
      at java.lang.Thread.run(Thread.java:745)
  ]]
  </code></pre>
  
  <p><strong>Research and findings</strong></p>
  
  <ul>
  <li>Debugging Validator.validateInjectionPointForDeploymentProblems() I
  saw, that the BeanManager of lib/shared.jar had the instance of AEjb
  in his enterpriseBeans collection. At no time this collection is used for look ups of dependencies. </li>
  <li>The injection of none-EJB classes (like AnotherCdiDependency) works fine in the classes of shared.jar</li>
  <li>Injecting AEjb via @Inject into AnotherCdiManagedBeanPojo that resides in b-ejb.jar (read: toplevel / outside of /lib) works fine as well</li>
  </ul>
  
  <p><strong>My questions</strong></p>
  
  <ul>
  <li><p>My first question: Why can't the BeanManager inject the EJB even
  if it knows about it?  Is there any standard that says shared libs
  can't be injected with "global" EJBs? If so where to find it?</p></li>
  <li><p>What would be the "easiest" way out of this? Where easy means changing as little code as possible and not creating a big mess we'll have trouble with later on.</p></li>
  <li><p>Bonus question: What is with this comment in
  BeanManagerImpl.getBeans(InjectionPoint injectionPoint) - where is this FAQ?</p>
  
  <blockquote>
    <p>We always cache, we assume that people don't use inline annotation literal declarations, a little risky but FAQd</p>
  </blockquote></li>
  </ul>
  
  <p>PS: I have read the following and a lot other stuff concerning classloading, context and cdi and the special behaviour of different application servers concerning those topics - but still...</p>
  
  <ul>
  <li><a href="https://struberg.wordpress.com/2015/02/18/cdi-in-ears/" rel="noreferrer">https://struberg.wordpress.com/2015/02/18/cdi-in-ears/</a>   </li>
  <li><a href="http://balusc.omnifaces.org/2013/10/cdi-behaved-unexpectedly-in-ear-so.html" rel="noreferrer">http://balusc.omnifaces.org/2013/10/cdi-behaved-unexpectedly-in-ear-so.html</a></li>
  </ul>
  
  <p>Disclaimer: No new was called during my research.</p>