title: Included CDI-enabled Servlet Fails with ContextNotActiveException: WELD-001303:
body: <p>I am writing a CDI application that runs on Tomcat. I am using Tomcat 7.0.62 with
  Weld 2.2.12.Final as the CDI implementation. I am using CDI without JSF.  </p>
  
  <p>The application consists of a dispatcher servlet that is not CDI enabled. The
  dispatcher includes the output of a CDI enabled servlet to create the page.   </p>
  
  <p>When the dispatcher servlet and the CDI servlet are both in the same web app, 
  it works fine. However, I need the CDI servlet to be in a different web app, so
  I do a cross-context include. When I do the cross-context include, the CDI servlet 
  produces output until it attempts to access an @RequestScoped bean. Bean 
  access fails with the following exception:  </p>
  
  <pre><code>org.jboss.weld.context.ContextNotActiveException: WELD-001303: No active contexts for scope type javax.enterprise.context.RequestScoped
      at org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:708)
      at org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:90)
      at org.jboss.weld.bean.ContextualInstanceStrategy$CachingContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:165)
      at org.jboss.weld.bean.ContextualInstance.getIfExists(ContextualInstance.java:63)
      at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:83)
  ...
  </code></pre>
  
  <p>I have tried activating CDI for the dispatcher servlet as well, but it doesn't 
  seem to make any difference.  </p>
  
  <p>It looks to me like the request context for the CDI servlet is not being set up
  properly when the CDI servlet is included as opposed to receiving the request 
  directly.  </p>
  
  <p>I have searched this site and also through Google, but have not found a matching
  problem / solution. I found a tomcat context setting 'fireRequestListenersOnForwards="true"'
  that I applied to the dispatcher servlet, but that did not make a difference.  </p>
  
  <p>Is this a configuration problem? Could anyone provide a clue about how to solve this?  </p>
  
  <p>I would be very grateful!  </p>
  
  <hr>
  
  <p><strong>Background information:</strong></p>
  
  <p>The actual application having the problem is large, so I condensed it down to get 
  to the essence of brokenness. As a result, I have two war files. The first war file
  contains the CDI servlet and the dispatcher (in code I called it the includer) servlet. The second war file contains only
  the dispatcher servlet.</p>
  
  <p><strong>The CDI Servlet</strong></p>
  
  <p>The CDI Servlet has a context.xml file in its META_INF directory with the following content:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;Context&gt;
      &lt;Resource name="BeanManager" 
          auth="Container"
          type="javax.enterprise.inject.spi.BeanManager"
          factory="org.jboss.weld.resources.ManagerObjectFactory" /&gt;
  &lt;/Context&gt;
  </code></pre>
  
  <p>The CDI servlet web.xml file contains the lines:</p>
  
  <pre><code>&lt;listener&gt;
    &lt;listener-class&gt;org.jboss.weld.environment.servlet.Listener&lt;/listener-class&gt;
  &lt;/listener&gt;
  
  &lt;resource-env-ref&gt;
      &lt;resource-env-ref-name&gt;BeanManager&lt;/resource-env-ref-name&gt;
      &lt;resource-env-ref-type&gt;javax.enterprise.inject.spi.BeanManager&lt;/resource-env-ref-type&gt;
  &lt;/resource-env-ref&gt;
  </code></pre>
  
  <p>The CDI Servlet WEB-INF directory contains a beans.xml file.</p>
  
  <p>The CDI servlet bootstraps bean execution through use of a BeanManager obtained 
  through JNDI lookup (this is working):</p>
  
  <pre><code>BeanManager bm = null;
  try {
      InitialContext context = new InitialContext();
  
      try {
         // "regular" naming
         bm = (BeanManager) context.lookup("java:comp/BeanManager");
      } catch(NameNotFoundException e) {
         // try again with Tomcat naming
         bm = (BeanManager) context.lookup("java:comp/env/BeanManager");
      }
  } catch (Exception e) {}
  
  if (bm == null) {
     writer.write("Couldn't look up the bean manager");
  } else {
     Set&lt;Bean&lt;?&gt;&gt; beans = bm.getBeans(EnclosingBean.class);
     @SuppressWarnings("unchecked")
     Bean&lt;EnclosingBean&gt; bean = (Bean&lt;EnclosingBean&gt;) bm.resolve(beans);
     if (bean == null) {
        writer.write("Couldn't get the bean");
     } else {
        EnclosingBean eb = (EnclosingBean) bm.getReference(bean, bean.getBeanClass(), bm.createCreationalContext(bean));
        writer.write("finally here we are. Name is: ");
        writer.write(eb.getName());
     }
  }
  </code></pre>
  
  <p><strong>The Includer (Dispatcher) Servlet</strong></p>
  
  <p>The includer servlet has a context.xml file in its META-INF directory:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;Context 
     path="/ExternalIncluderServlet" 
     docBase="ExternalIncluderServlet.war" 
     crossContext="true" 
     fireRequestListenersOnForwards="true"&gt;
  
      &lt;Resource name="BeanManager" 
          auth="Container"
          type="javax.enterprise.inject.spi.BeanManager"
          factory="org.jboss.weld.resources.ManagerObjectFactory" /&gt;
  &lt;/Context&gt;
  </code></pre>
  
  <p>The includer servlet looks up the context of the CDI servlet and obtains a 
  RequestDispatcher as follows (this works):</p>
  
  <pre><code>ServletContext sc = request.getServletContext();
  ServletContext extsc = sc.getContext("/SimpleCDIServlet");
  if (extsc == null) {
     writer.println("&lt;p&gt;Couldn't get the external context.&lt;/p&gt;");
  } else {
  
     RequestDispatcher rd = extsc.getRequestDispatcher("/CDIServlet");
     if (rd == null) {
          writer.println("&lt;p&gt;RequestDispatcher is null.&lt;/p&gt;");
     } else {
         writer.println("&lt;p&gt;Got the RequestDispatcher.&lt;/p&gt;");
         rd.include(req, resp);
     }
  }
  </code></pre>
  
  <p><strong>Results:</strong></p>
  
  <p>When I use the browser to access the CDI servlet directly via the URI: localhost:8080/SimpleCDIServlet/CDIServlet I get the expected output:</p>
  
  <pre><code>Simple CDI Servlet
  finally here we are. Name is: InjectedBean
  </code></pre>
  
  <p>If I access the CDI servlet through a dispatcher servlet located in the same web app as the CDI servlet, it works as well. URI: /SimpleCDIServlet/IncluderServlet, output:</p>
  
  <pre><code>Simple CDI Servlet Including Servlet
  Will now include the CDI servlet ...
  Got the RequestDispatcher.
  Simple CDI Servlet
  finally here we are. Name is: InjectedBean
  </code></pre>
  
  <p>But if I include the CDI servlet from a different context, I don't get the injected bean name in the output and the exception noted above is in the log. URI: /ExternalIncluderServlet/IncluderServlet, Output:</p>
  
  <pre><code>CDI Servlet Includer
  
  This servlet includes a CDI servlet in a different web app. It is not CDI enabled.
  
  Got the RequestDispatcher.
  Simple CDI Servlet
  finally here we are. Name is: 
  </code></pre>
  
  <p>Note that I can't use a request dispatcher forward instead of include as the original
  application includes output from several other servlets, not just one. And opening
  a new HTTP request for each include would be inefficient, since the number of requests
  would be multiplied by the number of included servlets, and it would be fairly ugly
  on top of that. </p>
  
  <hr>
  
  <p><strong>Update:</strong>
  I tried this out on Tomee 1.7.2 and also on WebSphere Application Server v8.5. The results are summarized below.</p>
  
  <pre>
                             WAS 8.5           Tomcat 7.0.62           Tomee 1.7.2
                             =======           =============           ===========
  CDI servlet direct access   works               works                   works
  
  Included by servlet         works               works                   works          
     in same web app
  
  Included by servlet         works               broken                  broken 
     in different web app
  </pre>
  
  <hr>
  
  <p>The more I think about this, the more I feel that it really should work. You should be able to
  successfully use a request dispatcher to include output from a CDI-enabled servlet on Tomcat.
  I hope that someone here can help me figure out how to make it work.</p>