Chapter 6. Standalone

In this chapter we will look at how the standalone deployment works. The examples use the following class (at time of writing). You do not have to use this class, you trivially write your own class that uses the BasicBootstrap and BeanXMLDeployer.

/*
 * JBoss, the OpenSource J2EE webOS
 * 
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package org.jboss.kernel.plugins.bootstrap.standalone;

import java.net.URL;
import java.util.Enumeration;
import java.util.List;
import java.util.ListIterator;

import org.jboss.kernel.plugins.bootstrap.basic.BasicBootstrap;
import org.jboss.kernel.plugins.deployment.xml.BeanXMLDeployer;
import org.jboss.kernel.spi.deployment.KernelDeployment;
import org.jboss.util.CollectionsFactory;

/**
 * Standalone Bootstrap of the kernel.
 * 
 * @author <a href="adrian@jboss.com">Adrian Brock</a>
 * @author <a href="mailto:les.hazlewood@jboss.org">Les A. Hazlewood</a>
 * @version $Revision: 1.4 $
 */
public class StandaloneBootstrap extends BasicBootstrap
{
   /** The deployer */
   protected BeanXMLDeployer deployer;
   
   /** The deployments */
   protected List deployments = CollectionsFactory.createCopyOnWriteList();
   
   /** The arguments */
   protected String[] args;
   
   /**
    * Bootstrap the kernel from the command line
    * 
    * @param args the command line arguments
    * @throws Exception for any error
    */
   public static void main(String[] args) throws Exception
   {
      StandaloneBootstrap bootstrap = new StandaloneBootstrap(args);
      bootstrap.run();
   }

   /**
    * Create a new bootstrap
    * 
    * @param args the arguments
    * @throws Exception for any error
    */
   public StandaloneBootstrap(String[] args) throws Exception
   {
      super();
      this.args = args;
   }
   
   public void bootstrap() throws Throwable
   {
      super.bootstrap();
      
      deployer = new BeanXMLDeployer(getKernel());
      
      Runtime.getRuntime().addShutdownHook(new Shutdown());
      
      ClassLoader cl = Thread.currentThread().getContextClassLoader();
      for (Enumeration e = cl.getResources(StandaloneKernelConstants.DEPLOYMENT_XML_NAME); e.hasMoreElements(); )
      {
         URL url = (URL) e.nextElement();
         deploy(url);
      }
      for (Enumeration e = cl.getResources("META-INF/" + StandaloneKernelConstants.DEPLOYMENT_XML_NAME); e.hasMoreElements(); )
      {
         URL url = (URL) e.nextElement();
         deploy(url);
      }
      
      // Validate that everything is ok
      deployer.validate();
   }
   
   /**
    * Deploy a url
    *
    * @param url the deployment url
    * @throws Throwable for any error  
    */
   protected void deploy(URL url) throws Throwable
   {
      log.debug("Deploying " + url);
      KernelDeployment deployment = deployer.deploy(url);
      deployments.add(deployment);
      log.debug("Deployed " + url);
   }
   
   /**
    * Undeploy a deployment
    * 
    * @param deployment the deployment
    */
   protected void undeploy(KernelDeployment deployment)
   {
      log.debug("Undeploying " + deployment.getName());
      deployments.remove(deployment);
      try
      {
         deployer.undeploy(deployment);
         log.debug("Undeployed " + deployment.getName());
      }
      catch (Throwable t)
      {
         log.warn("Error during undeployment: " + deployment.getName(), t);
      }
   }
   
   protected class Shutdown extends Thread
   {
      public void run()
      {
         log.info("Shutting down");
         ListIterator iterator = deployments.listIterator(deployments.size());
         while (iterator.hasPrevious())
         {
            KernelDeployment deployment = (KernelDeployment) iterator.previous();
            undeploy(deployment);
         }
      }
   }
}

One way to use this class in your own applications would be:

import org.jboss.kernel.plugins.bootstrap.standalone.StandaloneBootstrap

public MyMainClass
{
   public static void main(String[] args) throws Exception
   {
      StandaloneBootstrap.main(args);
      // Your stuff here...
   }
}

So what does the standalone bootstrap do?

First it does the plain bootstrap to get the "kernel" ready. You can think of this a sophisticated form of ServerLocator implementation.

It then creates a BeanXMLDeployer for deploying xml files.

Next it adds a shutdown hook, such that deployments are correctly "undeployed" in reverse order to their deployment.

Finally, it scans the classpath for META-INF/jboss.beans.xml and deploys every instance of that file it finds to populate the "kernel".

You can of course choose not to use this helper class and instead implement your own processing rules.