Save This Page
Home » jboss-5.0.0.CR1-src » org » jboss » system » [javadoc | source]
    1   /*
    2    * JBoss, Home of Professional Open Source
    3    * Copyright 2005, JBoss Inc., and individual contributors as indicated
    4    * by the @authors tag. See the copyright.txt in the distribution for a
    5    * full listing of individual contributors.
    6    *
    7    * This is free software; you can redistribute it and/or modify it
    8    * under the terms of the GNU Lesser General Public License as
    9    * published by the Free Software Foundation; either version 2.1 of
   10    * the License, or (at your option) any later version.
   11    *
   12    * This software is distributed in the hope that it will be useful,
   13    * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   15    * Lesser General Public License for more details.
   16    *
   17    * You should have received a copy of the GNU Lesser General Public
   18    * License along with this software; if not, write to the Free
   19    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
   20    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
   21    */
   22   package org.jboss.system;
   23   
   24   import java.net.URL;
   25   import java.util.List;
   26   
   27   import javax.management.MBeanServer;
   28   import javax.management.ObjectInstance;
   29   import javax.management.ObjectName;
   30   import javax.management.StandardMBean;
   31   
   32   import org.jboss.deployment.DeploymentException;
   33   import org.jboss.logging.Logger;
   34   import org.jboss.mx.server.ServerConstants;
   35   import org.jboss.mx.server.registry.MBeanEntry;
   36   import org.jboss.mx.service.ServiceConstants;
   37   import org.jboss.mx.util.JMXExceptionDecoder;
   38   import org.jboss.mx.util.ObjectNameFactory;
   39   import org.jboss.system.metadata.ServiceConstructorMetaData;
   40   import org.jboss.system.metadata.ServiceMetaData;
   41   import org.jboss.system.metadata.ServiceMetaDataParser;
   42   import org.jboss.util.UnreachableStatementException;
   43   import org.w3c.dom.Element;
   44   
   45   /**
   46    * A helper class for the controller.
   47    *
   48    * @see Service
   49    *
   50    * @author <a href="mailto:marc.fleury@jboss.org">Marc Fleury</a>
   51    * @author <a href="mailto:d_jencks@users.sourceforge.net">David Jencks</a>
   52    * @author <a href="adrian@jboss.com">Adrian Brock</a>
   53    * @version $Revision: 57108 $
   54    */
   55   public class ServiceCreator
   56   {
   57      /** Instance logger. */
   58      private static final Logger log = Logger.getLogger(ServiceCreator.class);
   59      
   60      /** The MBean Registry Object Name */
   61      private static ObjectName MBEAN_REGISTRY = ObjectNameFactory.create(ServerConstants.MBEAN_REGISTRY);
   62      
   63      /** The server */
   64      private MBeanServer server;
   65   
   66      /**
   67       * Install an MBean
   68       * 
   69       * @todo expand the meta data to include a pre-instantiated object
   70       * @param server the mbean server
   71       * @param objectName the object name
   72       * @param metaData the service metadata
   73       * @param mbean any mbean instance
   74       * @return the installed instance
   75       * @throws Exception for any error
   76       */
   77      public static ServiceInstance install(MBeanServer server, ObjectName objectName, ServiceMetaData metaData, Object mbean) throws Exception
   78      {
   79         if (server == null)
   80            throw new IllegalArgumentException("Null MBeanServer");
   81         if (objectName == null)
   82            throw new IllegalArgumentException("Null ObjectName");
   83         if (metaData == null && mbean == null)
   84            throw new IllegalArgumentException("Either metadata or an mbean object must be supplied");
   85         
   86         // Check for duplicate
   87         if (server.isRegistered(objectName))
   88            throw new DeploymentException("Trying to install an already registered mbean: " + objectName);
   89   
   90         try
   91         {
   92            ServiceInstance result = null; 
   93            
   94            // No meta data just register directly
   95            if (metaData == null)
   96            {
   97               ObjectInstance instance = server.registerMBean(mbean, objectName);
   98               result = new ServiceInstance(instance, mbean);
   99            }
  100            else
  101            {
  102               String code = metaData.getCode();
  103               if (code == null || code.trim().length() == 0)
  104                  throw new ConfigurationException("Missing or empty code for mbean " + objectName);
  105               
  106               String xmbeanDD = metaData.getXMBeanDD();
  107               
  108               // Not an XMBean
  109               if (xmbeanDD == null)
  110               {
  111                  String interfaceName = metaData.getInterfaceName();
  112                  if (interfaceName != null)
  113                     result = installStandardMBean(server, objectName, metaData);
  114                  else
  115                     result = installPlainMBean(server, objectName, metaData);
  116               }
  117               // Embedded XMBean Descriptor
  118               else if (xmbeanDD.length() == 0)
  119                  result = installEmbeddedXMBean(server, objectName, metaData);
  120               // Reference to external XMBean descriptor
  121               else
  122                  result = installExternalXMBean(server, objectName, metaData);
  123            }
  124   
  125            log.debug("Created mbean: " + objectName);
  126            return result;
  127         }
  128         catch (Throwable e)
  129         {
  130            Throwable newE = JMXExceptionDecoder.decode(e);
  131   
  132            // didn't work, unregister in case the jmx agent is screwed.
  133            try
  134            {
  135               server.unregisterMBean(objectName);
  136            }
  137            catch (Throwable ignore)
  138            {
  139            }
  140   
  141            DeploymentException.rethrowAsDeploymentException("Unable to createMBean for " + objectName, newE);
  142            throw new UnreachableStatementException();
  143         }
  144      }
  145   
  146      /**
  147       * Install a StandardMBean
  148       * 
  149       * @param server the mbean server
  150       * @param objectName the object name
  151       * @param metadata the service metadata
  152       * @return the installed instance
  153       * @throws Exception for any error
  154       */
  155      private static ServiceInstance installStandardMBean(MBeanServer server, ObjectName objectName, ServiceMetaData metaData) throws Exception
  156      {
  157         ObjectName loaderName = metaData.getClassLoaderName();
  158         ClassLoader loader = server.getClassLoader(loaderName);
  159         String code = metaData.getCode();
  160         ServiceConstructorMetaData constructor = metaData.getConstructor();
  161         String interfaceName = metaData.getInterfaceName();
  162   
  163         Class intf = loader.loadClass(interfaceName);
  164         log.debug("About to create bean resource: " + objectName + " with code: " + code + " and interface " + interfaceName);
  165         Object resource = server.instantiate(code,
  166                                              loaderName,
  167                                              constructor.getParameters(loader),
  168                                              constructor.getSignature());
  169   
  170         log.debug("About to register StandardMBean : " + objectName);
  171         ObjectInstance instance = server.createMBean(StandardMBean.class.getName(),
  172                                                      objectName,
  173                                                      loaderName,
  174                                                      new Object[] { resource, intf },
  175                                                      new String[] { Object.class.getName() , Class.class.getName() });
  176         return new ServiceInstance(instance, resource);
  177      }
  178   
  179      /**
  180       * Install a plain MBean
  181       * 
  182       * @param server the mbean server
  183       * @param objectName the object name
  184       * @param metadata the service metadata
  185       * @return the installed instance
  186       * @throws Exception for any error
  187       */
  188      private static ServiceInstance installPlainMBean(MBeanServer server, ObjectName objectName, ServiceMetaData metaData) throws Exception
  189      {
  190         ObjectName loaderName = metaData.getClassLoaderName();
  191         ClassLoader loader = server.getClassLoader(loaderName);
  192         String code = metaData.getCode();
  193         ServiceConstructorMetaData constructor = metaData.getConstructor();
  194         
  195         // This is a standard or dynamic mbean
  196         log.debug("About to create bean: " + objectName + " with code: " + code);
  197         ObjectInstance instance = server.createMBean(code,
  198                                                      objectName,
  199                                                      loaderName,
  200                                                      constructor.getParameters(loader),
  201                                                      constructor.getSignature());
  202   
  203         MBeanEntry entry = (MBeanEntry) server.invoke(MBEAN_REGISTRY, "get", new Object[] { objectName }, new String[] { ObjectName.class.getName() });
  204         Object resource = entry.getResourceInstance();
  205         return new ServiceInstance(instance, resource);
  206      }
  207   
  208      /**
  209       * Install an embedded XMBean
  210       * 
  211       * @param server the mbean server
  212       * @param objectName the object name
  213       * @param metadata the service metadata
  214       * @return the installed instance
  215       * @throws Exception for any error
  216       */
  217      private static ServiceInstance installEmbeddedXMBean(MBeanServer server, ObjectName objectName, ServiceMetaData metaData) throws Exception
  218      {
  219         ObjectName loaderName = metaData.getClassLoaderName();
  220         ClassLoader loader = server.getClassLoader(loaderName);
  221         String code = metaData.getCode();
  222         ServiceConstructorMetaData constructor = metaData.getConstructor();
  223   
  224         // This is an xmbean with an embedded mbean descriptor
  225         log.debug("About to create xmbean object: " + objectName + " with code: " + code + " with embedded descriptor");
  226         //xmbean: construct object first.
  227         Object resource = server.instantiate(code, 
  228                                              loaderName,
  229                                              constructor.getParameters(loader), 
  230                                              constructor.getSignature());
  231   
  232         String xmbeanCode = metaData.getXMBeanCode();
  233         Element mbeanDescriptor = metaData.getXMBeanDescriptor();
  234         Object[] args = { resource, mbeanDescriptor, ServiceConstants.PUBLIC_JBOSSMX_XMBEAN_DTD_1_0 };
  235         String[] sig = { Object.class.getName(), Element.class.getName(), String.class.getName() };
  236         ObjectInstance instance = server.createMBean(xmbeanCode,
  237                                                      objectName,
  238                                                      loaderName,
  239                                                      args,
  240                                                      sig);
  241         return new ServiceInstance(instance, resource);
  242      }
  243   
  244      /**
  245       * Install an external XMBean
  246       * 
  247       * @param server the mbean server
  248       * @param objectName the object name
  249       * @param metadata the service metadata
  250       * @return the installed instance
  251       * @throws Exception for any error
  252       */
  253      private static ServiceInstance installExternalXMBean(MBeanServer server, ObjectName objectName, ServiceMetaData metaData) throws Exception
  254      {
  255         ObjectName loaderName = metaData.getClassLoaderName();
  256         ClassLoader loader = server.getClassLoader(loaderName);
  257         String code = metaData.getCode();
  258         ServiceConstructorMetaData constructor = metaData.getConstructor();
  259         String xmbeanDD = metaData.getXMBeanDD();
  260         
  261         // This is an xmbean with an external descriptor
  262         log.debug("About to create xmbean object: " + objectName  + " with code: " + code + " with descriptor: " + xmbeanDD);
  263         //xmbean: construct object first.
  264         Object resource = server.instantiate(code, 
  265                                              loaderName, 
  266                                              constructor.getParameters(loader), 
  267                                              constructor.getSignature());
  268         // Try to find the dd first as a resource then as a URL
  269         URL xmbeanddUrl = null;
  270         try
  271         {
  272            xmbeanddUrl = resource.getClass().getClassLoader().getResource(xmbeanDD);
  273         }
  274         catch (Exception e)
  275         {
  276         }
  277   
  278         if (xmbeanddUrl == null)
  279            xmbeanddUrl = new URL(xmbeanDD);
  280   
  281         String xmbeanCode = metaData.getXMBeanCode();
  282   
  283         //now create the mbean
  284         Object[] args = { resource, xmbeanddUrl };
  285         String[] sig = { Object.class.getName(), URL.class.getName() };
  286         ObjectInstance instance = server.createMBean(xmbeanCode,
  287                                                      objectName,
  288                                                      loaderName,
  289                                                      args,
  290                                                      sig);
  291         return new ServiceInstance(instance, resource);
  292      }
  293   
  294      /**
  295       * Uninstall an MBean
  296       * 
  297       * @param server the mbean server
  298       * @param objectName the object name
  299       */
  300      public static void uninstall(MBeanServer server, ObjectName objectName)
  301      {
  302         if (server == null)
  303            throw new IllegalArgumentException("Null MBeanServer");
  304         if (objectName == null)
  305            throw new IllegalArgumentException("Null ObjectName");
  306         try
  307         {
  308            log.debug("Removing mbean from server: " + objectName);
  309            server.unregisterMBean(objectName);
  310         }
  311         catch (Throwable t)
  312         {
  313            log.debug("Error unregistering mbean " + objectName, t);
  314         }
  315      }
  316      
  317      /**
  318       * Create a new ServiceCreator
  319       * 
  320       * @deprecated This is no longer used and will be going away
  321       * @param server the mbean server
  322       */
  323      public ServiceCreator(final MBeanServer server)
  324      {
  325         if (server == null)
  326            throw new IllegalArgumentException("Null MBeanServer");
  327         this.server = server;
  328      }
  329      
  330      /**
  331       * Clean shutdown
  332       */
  333      public void shutdown()
  334      {
  335         this.server = null;
  336      } 
  337      
  338      /**
  339       * Parses the given configuration document and creates MBean
  340       * instances in the current MBean server.
  341       *
  342       * @deprecated This is no longer used and will be going away
  343       * @param mbeanName the object name
  344       * @param loaderName the classloader
  345       * @param mbeanElement the config
  346       * @return the created object instance
  347       * @throws Exception for any error
  348       */
  349      public ObjectInstance install(ObjectName mbeanName, ObjectName loaderName, Element mbeanElement) throws Exception
  350      {
  351         if (mbeanName == null)
  352            throw new IllegalArgumentException("Null mbeanName");
  353         if (mbeanElement == null)
  354            throw new IllegalArgumentException("Null mbean element");
  355         
  356         ServiceMetaDataParser parser = new ServiceMetaDataParser(mbeanElement);
  357         List<ServiceMetaData> metaDatas = parser.parse();
  358         if (metaDatas.isEmpty())
  359            throw new DeploymentException("No mbeans found in passed configuration for " + mbeanName);
  360         ServiceMetaData metaData = metaDatas.get(0);
  361         metaData.setClassLoaderName(loaderName);
  362         ServiceInstance instance = install(server, mbeanName, metaData, null);
  363         return instance.getObjectInstance();
  364      }
  365      
  366      /**
  367       * Remove the installed object
  368       * 
  369       * @param name the object name
  370       * @throws Exception for any error
  371       */
  372      public void remove(ObjectName name) throws Exception
  373      {
  374         if (name == null)
  375            throw new IllegalArgumentException("Null name");
  376         uninstall(server, name);
  377      }
  378   }

Save This Page
Home » jboss-5.0.0.CR1-src » org » jboss » system » [javadoc | source]