Package org.jboss.system.server.jmx

Source Code of org.jboss.system.server.jmx.JMXKernel

/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.system.server.jmx;

import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.Map;

import javax.management.ListenerNotFoundException;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.NotificationEmitter;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.ObjectInstance;
import javax.management.ObjectName;

import org.jboss.bootstrap.spi.ServerConfig;
import org.jboss.bootstrap.spi.ServerProcess;
import org.jboss.classloader.spi.ClassLoaderSystem;
import org.jboss.classloading.spi.RealClassLoader;
import org.jboss.classloading.spi.metadata.ExportAll;
import org.jboss.classloading.spi.vfs.policy.VFSClassLoaderPolicy;
import org.jboss.kernel.Kernel;
import org.jboss.mx.loading.RepositoryClassLoader;
import org.jboss.mx.server.ServerConstants;
import org.jboss.mx.util.JMXExceptionDecoder;
import org.jboss.mx.util.MBeanServerLocator;
import org.jboss.mx.util.ObjectNameFactory;
import org.jboss.system.ServiceController;
import org.jboss.system.ServiceControllerMBean;
import org.jboss.system.server.ServerConfigImpl;
import org.jboss.system.server.ServerConfigImplMBean;
import org.jboss.system.server.ServerImplMBean;
import org.jboss.system.server.ServerInfoMBean;
import org.jboss.util.JBossObject;
import org.jboss.util.file.FileSuffixFilter;
import org.jboss.virtual.VFS;
import org.jboss.virtual.VirtualFile;

/**
* A pojo that creates a legacy jmx kernel ala the jboss-4.x server bootstrap.
* This is used to support the SARDeployer and mbean integration.
*
* @author Scott.Stark@jboss.org
* @version $Revision: 85945 $
*/
public class JMXKernel extends JBossObject
   implements JMXKernelMBean, NotificationEmitter
{
   private final static ObjectName DEFAULT_LOADER_NAME =
      ObjectNameFactory.create(ServerConstants.DEFAULT_LOADER_NAME);

   /** The JMX MBeanServer which will serve as our communication bus. */
   private MBeanServer mbeanServer;
   private ServerProcess serverImpl;
   private ServiceController controller;
   private ServerConfig serverConfig;
   private ServerConfigImplMBean serverConfigMBean;
   private ServerInfoMBean serverInfo;
   /** The kernel */
   private Kernel kernel;
   /** The serverImpl cast as an emitter */
   private NotificationEmitter notificationEmitter;
  
   /** The bootstrap UCL class loader ObjectName */
   private ObjectName bootstrapUCLName;
   private boolean started;
   /** Whether to use the old classloader */
   private boolean oldClassLoader;
  
   public ServerProcess getServerImpl()
   {
      return serverImpl;
   }
   public void setServerImpl(ServerProcess serverImpl)
   {
      this.serverImpl = serverImpl;
      this.notificationEmitter = (NotificationEmitter) serverImpl;
   }

   public ServiceControllerMBean getServiceController()
   {
      return this.controller;
   }
   public MBeanServer getMbeanServer()
   {
      return mbeanServer;
   }

   /**
    * Get the optional server configuration metadata
    * @return a possibly empty map of configuration metadata.
    */
   @SuppressWarnings("unchecked")
   public Map<String, Object> getMetaData()
   {
      return Collections.emptyMap();
   }


   public ServerInfoMBean getServerInfo()
   {
      return serverInfo;
   }

   /**
    * Initialize the Server instance.
    *
    * @param props     The configuration properties for the server.
    * @param metadata configuration metadata for the server
    *
    * @throws IllegalStateException    Already initialized.
    * @throws Exception                Failed to initialize.
    */
   public void init(Properties props, Map<String, Object> metaData) throws IllegalStateException, Exception
   {
      return; //NOOP for now
   }


   public void setServerInfo(ServerInfoMBean serverInfo)
   {
      this.serverInfo = serverInfo;
   }

   /**
    * Set the kernel.
    *
    * @param kernel the kernel.
    */
   public void setKernel(Kernel kernel)
   {
      this.kernel = kernel;
   }
  
   public boolean isOldClassLoader()
   {
      return oldClassLoader;
   }

   public void setOldClassLoader(boolean oldClassLoader)
   {
      this.oldClassLoader = oldClassLoader;
   }
  
   public void start() throws Exception
   {
      ClassLoader tcl = Thread.currentThread().getContextClassLoader();
      // Create the MBeanServer
      String builder = System.getProperty(ServerConstants.MBEAN_SERVER_BUILDER_CLASS_PROPERTY,
                                          ServerConstants.DEFAULT_MBEAN_SERVER_BUILDER_CLASS);
      System.setProperty(ServerConstants.MBEAN_SERVER_BUILDER_CLASS_PROPERTY, builder);

      serverConfig = serverImpl.getConfig();
      serverConfigMBean = new ServerConfigImpl(serverConfig);
      // Check if we'll use the platform MBeanServer or instantiate our own
      if (serverConfig.getPlatformMBeanServer() == true)
      {
         // jdk1.5+
         ClassLoader cl = Thread.currentThread().getContextClassLoader();
         Class clazz = cl.loadClass("java.lang.management.ManagementFactory");
         Class[] sig = null;
         Method method = clazz.getMethod("getPlatformMBeanServer", sig);
         Object[] args = null;
         mbeanServer = (MBeanServer) method.invoke(null, args);
         // Tell the MBeanServerLocator to point to this mbeanServer
         MBeanServerLocator.setJBoss(mbeanServer);
         /* If the LazyMBeanServer was used, we need to reset to the jboss
         MBeanServer to use our implementation for the jboss services.
         */
         mbeanServer = LazyMBeanServer.resetToJBossServer(mbeanServer);
      }
      else
      {
         // Create our own MBeanServer
         mbeanServer = MBeanServerFactory.createMBeanServer("jboss");
      }
      log.debug("Created MBeanServer: " + mbeanServer);     

      // Register mbeanServer components
      mbeanServer.registerMBean(this, ServerImplMBean.OBJECT_NAME);
      mbeanServer.registerMBean(serverConfigMBean, ServerConfigImplMBean.OBJECT_NAME);
     
      // Initialize spine boot libraries
      ClassLoader cl;
      if (oldClassLoader)
         cl = initBootLibrariesOld();
      else
         cl = initBootLibraries();
     
      // Set ServiceClassLoader as classloader for the construction of
      // the basic system
      try
      {
         Thread.currentThread().setContextClassLoader(cl);
  
         // General Purpose Architecture information --
         mbeanServer.registerMBean(serverInfo, new ObjectName("jboss.system:type=ServerInfo"));

         // Service Controller
         controller = new ServiceController();
         controller.setKernel(kernel);
         controller.setMBeanServer(mbeanServer);
         mbeanServer.registerMBean(controller, new ObjectName("jboss.system:service=ServiceController"));
  
         log.info("Legacy JMX core initialized");
         started = true;
      }
      finally
      {
         Thread.currentThread().setContextClassLoader(tcl);
      }
   }

   /**
    * Stop the mbeans
    *
    * @throws IllegalStateException - if not started.
    */
   public void stop() throws IllegalStateException
   {
      if (log.isTraceEnabled())
         log.trace("stop caller:", new Throwable("Here"));

      if (!started)
         throw new IllegalStateException("Server not started");

      log.debug("Shutting down all services");
      shutdownServices();

      // Make sure all mbeans are unregistered
      removeMBeans();
   }

   ///////////////////////////////////////////////////////////////////////////
   //                          NotificationEmitter                          //
   ///////////////////////////////////////////////////////////////////////////
  
   public void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback)
   {
      notificationEmitter.addNotificationListener(listener, filter, handback);
   }
  
   public void removeNotificationListener(NotificationListener listener) throws ListenerNotFoundException
   {
      notificationEmitter.removeNotificationListener(listener);
   }
  
   public void removeNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback)
      throws ListenerNotFoundException
   {
      notificationEmitter.removeNotificationListener(listener, filter, handback);
   }
     
   public MBeanNotificationInfo[] getNotificationInfo()
   {
      return notificationEmitter.getNotificationInfo();
   }

   // ServerImplMBean delegation
   public void init(Properties props) throws Exception
   {
      serverImpl.init(props);
   }

   public void exit()
   {
      serverImpl.exit();
   }

   public void exit(int exitcode)
   {
      serverImpl.exit(exitcode);
   }

   public ServerConfig getConfig()
   {
      return serverConfig;
   }
   public String getBuildDate()
   {
      return serverImpl.getBuildDate();
   }

   public String getBuildID()
   {
      return serverImpl.getBuildID();
   }

   public String getBuildJVM()
   {
      return serverImpl.getBuildJVM();
   }

   public String getBuildNumber()
   {
      return serverImpl.getBuildNumber();
   }

   public String getBuildOS()
   {
      return serverImpl.getBuildOS();
   }

   public Date getStartDate()
   {
      return serverImpl.getStartDate();
   }

   public String getVersion()
   {
      return serverImpl.getVersion();
   }

   public String getVersionName()
   {
      return serverImpl.getVersionName();
   }

   public String getVersionNumber()
   {
      return serverImpl.getVersionNumber();
   }

   public void halt()
   {
      serverImpl.halt();
   }

   public void halt(int exitcode)
   {
      serverImpl.halt(exitcode);
   }

   public boolean isInShutdown()
   {
      return serverImpl.isInShutdown();
   }

   public boolean isStarted()
   {
      return serverImpl.isStarted();
   }

   public void runFinalization()
   {
     
   }

   public void runGarbageCollector()
   {
     
   }

   public void traceInstructions(Boolean flag)
   {
     
   }

   public void traceMethodCalls(Boolean flag)
   {
     
   }
  
   public void shutdown()
   {
      if (log.isTraceEnabled())
         log.trace("Shutdown caller:", new Throwable("Here"));
      serverImpl.shutdown();
   }

   /**
    * The <code>shutdownServices</code> method calls the one and only
    * ServiceController to shut down all the mbeans registered with it.
    */
   protected void shutdownServices()
   {
      try
      {
         // get the deployed objects from ServiceController
         controller.shutdown();
      }
      catch (Exception e)
      {
         Throwable t = JMXExceptionDecoder.decode(e);
         log.error("Failed to shutdown services", t);
      }
   }

   /**
    * The <code>removeMBeans</code> method uses the mbean mbeanServer to unregister
    * all the mbeans registered here.
    */
   protected void removeMBeans()
   {
      try
      {
         mbeanServer.unregisterMBean(ServerConfigImplMBean.OBJECT_NAME);
      }
      catch (Exception e)
      {
         Throwable t = JMXExceptionDecoder.decode(e);
         log.error("Failed to unregister mbeans", t);
      }
      try
      {
         mbeanServer.unregisterMBean(ServerImplMBean.OBJECT_NAME);
      }
      catch (Exception e)
      {
         Throwable t = JMXExceptionDecoder.decode(e);
         log.error("Failed to unregister mbeans", t);
      }
      try
      {
         MBeanServer registeredServer = mbeanServer;
         if (serverConfig.getPlatformMBeanServer() == true)
            registeredServer = LazyMBeanServer.getRegisteredMBeanServer(mbeanServer);
         MBeanServerFactory.releaseMBeanServer(registeredServer);
      }
      catch (Exception e)
      {
         Throwable t = JMXExceptionDecoder.decode(e);
         log.error("Failed to release mbean mbeanServer", t);
      }
   }


   /**
    * Initialize the boot libraries using the old classloader
    *
    * @return the classloader
    * @throws Exception for any error
    */
   private List<URL> getBootURLs() throws Exception
   {
      // Build the list of URL for the spine to boot
      List<URL> list = new ArrayList<URL>();

      // Add the patch URL.  If the url protocol is file, then
      // add the contents of the directory it points to
      URL patchURL = serverConfig.getPatchURL();
      if (patchURL != null)
      {
         if (patchURL.getProtocol().equals("file"))
         {
            File dir = new File(patchURL.getFile());
            if (dir.exists())
            {
               // Add the local file patch directory
               list.add(dir.toURL());

               // Add the contents of the directory too
               File[] jars = dir.listFiles(new FileSuffixFilter(new String[] { ".jar", ".zip" }, true));

               for (int j = 0; jars != null && j < jars.length; j++)
               {
                  list.add(jars[j].getCanonicalFile().toURL());
               }
            }
         }
         else
         {
            list.add(patchURL);
         }
      }

      // Add the mbeanServer configuration directory to be able to load serverConfig files as resources
      list.add(serverConfig.getServerConfigURL());
      log.debug("Boot url list: " + list);
     
      return list;
   }

   /**
    * Initialize the boot libraries using the old classloader
    *
    * @return the classloader
    * @throws Exception for any error
    */
   private ClassLoader initBootLibrariesOld() throws Exception
   {
      List<URL> list = getBootURLs();
     
      // Create loaders for each URL
      RepositoryClassLoader loader = null;
      for (URL url : list)
      {
         log.debug("Creating loader for URL: " + url);

         // This is a boot URL, so key it on itself.
         Object[] args = {url, Boolean.TRUE};
         String[] sig = {"java.net.URL", "boolean"};
         loader = (RepositoryClassLoader) mbeanServer.invoke(DEFAULT_LOADER_NAME, "newClassLoader", args, sig);
      }
      bootstrapUCLName = loader.getObjectName();
      mbeanServer.registerMBean(loader, bootstrapUCLName);
      return loader;
   }

   /**
    * Initialize the boot libraries using the new classloader
    *
    * @return the classloader
    * @throws Exception for any error
    */
   private ClassLoader initBootLibraries() throws Exception
   {
      ClassLoaderSystem system = ClassLoaderSystem.getInstance();
      mbeanServer.registerMBean(system, new ObjectName("jboss.classloader:service=ClassLoaderSystem"));
     
      List<URL> list = getBootURLs();

      VirtualFile[] files = new VirtualFile[list.size()];
      for (int i = 0; i < list.size(); ++i)
      {
         URL url = list.get(i);
         files[i] = VFS.getRoot(url);
      }
     
      VFSClassLoaderPolicy policy = new VFSClassLoaderPolicy(files);
      policy.setExportAll(ExportAll.NON_EMPTY);
      policy.setImportAll(true);
      ClassLoader classLoader = system.registerClassLoaderPolicy(policy);
      if (classLoader instanceof RealClassLoader)
         bootstrapUCLName = ((RealClassLoader) classLoader).getObjectName();
      return classLoader;
   }

   /**
    * Instantiate and register a service for the given classname into the MBean mbeanServer.
    *
    * @param classname the mbean class name
    * @param name the obejct name
    * @return the object name
    * @throws Exception for any error
    */
   private ObjectName createMBean(final String classname, String name)
      throws Exception
   {
      ObjectName mbeanName = null;
      if( name != null )
         mbeanName = new ObjectName(name);
      try
      {
         // See if there is an xmbean descriptor for the bootstrap mbean
         URL xmbeanDD = new URL("resource:xmdesc/"+classname+"-xmbean.xml");
         Object resource = mbeanServer.instantiate(classname);
         // Create the XMBean
         Object[] args = {resource, xmbeanDD};
         String[] sig = {Object.class.getName(), URL.class.getName()};
         ObjectInstance instance = mbeanServer.createMBean("org.jboss.mx.modelmbean.XMBean",
                                       mbeanName,
                                       bootstrapUCLName,
                                       args,
                                       sig);
         mbeanName = instance.getObjectName();
         log.debug("Created system XMBean: "+mbeanName);
      }
      catch(Exception e)
      {
         log.debug("Failed to create xmbean for: "+classname);
         mbeanName = mbeanServer.createMBean(classname, mbeanName).getObjectName();
         log.debug("Created system MBean: " + mbeanName);
      }

      return mbeanName;
   }
}

TOP

Related Classes of org.jboss.system.server.jmx.JMXKernel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.