SeamFramework.orgCommunity Documentation

Chapter 10. Obtaining a reference to the BeanManager

When developing a framework that builds on CDI, you may need to obtain the BeanManager for the application, you can't simply inject it as you are not working in an object managed by the container. The CDI specification allows lookup of java:comp/BeanManager in JNDI, however, some environments don't support binding to this location (e.g. servlet containers such as Tomcat and Jetty) and some environments don't support JNDI (e.g. the Weld SE container). For this reason, most framework developers will prefer to avoid a direct JNDI lookup.

Often it is possible to pass the correct BeanManager to the object in which you require it, for example via a context object. For example, you might be able to place the BeanManager in the ServletContext, and retrieve it at a later date.

On some occasions however there is no suitable context to use, and in this case, you can take advantage of the abstraction over BeanManager lookup provided by Solder. To lookup up a BeanManager, you can extend the abstract BeanManagerAware class, and call getBeanManager():

public class WicketIntegration extends BeanManagerAware {


   public WicketManager getWicketManager() {
      Bean<?> bean = getBeanManager().getBeans(IRequestListener.class);
      ... // and so on to lookup the bean
   }
   
}

The benefit here is that BeanManagerAware class will first look to see if its BeanManager injection point was satisfied before consulting the providers. Thus, if injection becomes available to the class in the future, it will automatically start the more efficient approach.

Occasionally you will be working in an existing class hierarchy, in which case you can use the accessor on BeanManagerLocator. For example:

public class ResourceServlet extends HttpServlet {


   protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
         throws ServletException, IOException {
      BeanManager beanManager = new BeanManagerLocator().getBeanManager();
      ...
   }
}

If this lookup fails to resolve a BeanManager, the BeanManagerUnavailableException, a runtime exception, will be thrown. If you want to perform conditional logic based on whether the BeanManager is available, you can use this check:

public class ResourceServlet extends HttpServlet {


   protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
         throws ServletException, IOException {
      BeanManagerLocator locator = new BeanManagerLocator();
      if (locator.isBeanManagerAvailable()) {
         BeanManager beanManager = locator.getBeanManager();
         ... // work with the BeanManager
      }
      else {
         ... // work without the BeanManager
      }
   }
}

However, keep in mind that you can inject into Servlets in Java EE 6!! So it's very likely the lookup isn't necessary, and you can just do this:

public class ResourceServlet extends HttpServlet {


   @Inject
   private BeanManager beanManager;
   protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
         throws ServletException, IOException {
      ... // work with the BeanManager
   }
}