1 Reply Latest reply on Jul 28, 2008 4:23 PM by starksm64

    MC bean integration into Tomcat startup


      In my work on ModClusterService, I'm facing an issue integrating MC beans into Tomcat and would appreciate any comments on my solution. My requirements:

      1) Make mc beans available to Tomcat components. Specifically add a LifecycleListener to the TC Server object. The listener has various other beans injected into it; i.e. it needs to be built by the MC.
      2) TC component is created as part of server.xml processing, i.e. it's not something we add later via JBoss AS code.
      3) MC beans need to be available to TC component before the component is started.

      Problem is the TC's server.xml processing works, the components listed in server.xml are both instantiated and started in a single call -- by TomcatService to org.apache.catalina.startup.Catalina.start(). So, there's no opportunity to inject anything before the components are started.

      Perhaps JBAS-5672 work will fundamentally change how this is all done. But for now I've gotten something clunky working that allows me to test ModClusterService. I'd appreciate comments on this general approach before I commit it.

      Basically, in server.xml I configure the LifecycleListener class I want to use. It includes a config attribute where the name of the MC bean it needs is specified. The listener uses a service locator to find the object.

      package org.jboss.web.tomcat.service.deployers;
      import org.jboss.dependency.spi.ControllerContext;
      import org.jboss.kernel.spi.dependency.KernelController;
      public class JBossWebMicrocontainerBeanLocator
       private static KernelController kernelController;
       * Returns the microcontainer bean installed under the given name.
       * @param beanName the name of the bean
       * @return the bean, or <code>null</code> if no bean is installed under <code>name</code>
       * @throws IllegalStateException if no KernelController is available to perform
       * the lookup
       public static Object getInstalledBean(Object beanName)
       if (kernelController == null)
       throw new IllegalStateException("KernelController not installed");
       ControllerContext context = kernelController.getInstalledContext(beanName);
       return context == null ? null : context.getTarget();
       /** Package-protected accessible to TomcatService */
       static void setKernelController(KernelController controller)
       kernelController = controller;
       /** Prevent instantiation */
       private JBossWebMicrocontainerBeanLocator()

      The KernelController is provided to the locator by the TomcatService bean, which is KernelControllerContextAware. Ensures the correct KernelController is used.

      The same general approach could be used by other TC components (e.g. specialized valves) that are deployed via server.xml but need access to MC beans.

      If there's an equivalent general purpose equivalent service locator that will use the correct KernelController out there in the AS somewhere, I could use that instead of having TomcatService provide it. A downside of having TomcatService provide the KernelController is I've found that the KernelControllerContextAware callbacks only get invoked if the TomcatService is deployed via a -beans.xml. With the current deployment via jboss-service.xml the callbacks are not getting invoked. (The conversion to -beans.xml is no big deal, except it further breaks the already-broken ServiceBindingManager.)

        • 1. Re: MC bean integration into Tomcat startup

          There is a general org.jboss.kernel.plugins.util.KernelLocator, but you can just inject it as is done by the profile-service:

           <property name="controller"><inject bean="jboss.kernel:service=Kernel" property="controller"/></property>

          Ales is also looking for more mc integration, so I think we need to look at taking more control of the initialization of the jbossweb pieces. I'll look at creating some subtasks under the JBAS-5672 as we explore this more.