User: user57  
  Date: 02/02/24 02:24:34

  Modified:    src/main/org/jboss/system/server Server.java
                        ServerConfig.java ServerImpl.java ServerLoader.java
  Added:       src/main/org/jboss/system/server ServerConfigImpl.java
                        ServerConfigImplMBean.java ServerImplMBean.java
                        ServerInfo.java ServerInfoMBean.java
  Log:
   o moved core system from server to system (includes
     all of org.jboss.system, some of org.jboss.deployment +
     Main, Shutdown & Version)
   o finished the integration of ServerLoader, Server and
     ServerConfig are now interfaces so had to update refering
     classes to use ServerConfigImplMBean
   o ServerLoader changes effectivly remove the need for lib/ + lib/ext
     seperation, updated build to use lib for lib/ext and updated
     config files
  
  Revision  Changes    Path
  1.2       +24 -9     jboss-system/src/main/org/jboss/system/server/Server.java
  
  Index: Server.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-system/src/main/org/jboss/system/server/Server.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Server.java       22 Feb 2002 08:00:45 -0000      1.1
  +++ Server.java       24 Feb 2002 10:24:34 -0000      1.2
  @@ -9,12 +9,12 @@
   
   package org.jboss.system.server;
   
  -import java.util.Map;
  +import java.util.Properties;
   
   /**
    * The interface of the basic JBoss server component.
    *
  - * @version <tt>$Revision: 1.1 $</tt>
  + * @version <tt>$Revision: 1.2 $</tt>
    * @author  <a href="mailto:[EMAIL PROTECTED]";>Jason Dillon</a>
    */
   public interface Server
  @@ -28,7 +28,7 @@
       * @throws IllegalStateException    Already initialized.
       * @throws Exception                Failed to initialize.
       */
  -   void init(Map props) throws IllegalStateException, Exception;
  +   void init(Properties props) throws IllegalStateException, Exception;
   
      /**
       * Get the typed server configuration object which the
  @@ -49,18 +49,33 @@
      void start() throws IllegalStateException, Exception;
   
      /**
  -    * Shutdown the Server instance.
  +    * Check if the server is started.
  +    *
  +    * @return   True if the server is started, else false.
  +    */
  +   boolean isStarted();
  +
  +   /**
  +    * Shutdown the Server instance and run shutdown hooks.  
  +    *
  +    * <p>If the exit on shutdown flag is true, then {@link #exit} 
  +    *    is called, else only the shutdown hook is run.
       *
       * @throws IllegalStateException    No started.
  -    * @throws Exception                Failed to shutdown.
       */
  -   void shutdown() throws IllegalStateException, Exception;
  +   void shutdown() throws IllegalStateException;
   
      /**
  -    * Check if the server is started.
  +    * Shutdown the server, the JVM and run shutdown hooks.
       *
  -    * @return   True if the server is started, else false.
  +    * @param exitcode   The exit code returned to the operating system.
       */
  -   boolean isStarted();
  +   void exit(int exitcode);
   
  +   /** 
  +    * Forcibly terminates the currently running Java virtual machine.
  +    *
  +    * @param exitcode   The exit code returned to the operating system.
  +    */
  +   void halt(int exitcode);
   }
  
  
  
  1.2       +25 -6     jboss-system/src/main/org/jboss/system/server/ServerConfig.java
  
  Index: ServerConfig.java
  ===================================================================
  RCS file: 
/cvsroot/jboss/jboss-system/src/main/org/jboss/system/server/ServerConfig.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ServerConfig.java 22 Feb 2002 08:00:45 -0000      1.1
  +++ ServerConfig.java 24 Feb 2002 10:24:34 -0000      1.2
  @@ -16,7 +16,7 @@
   /**
    * The interface of the basic <em>typed</em> JBoss server configuration.
    *
  - * @version <tt>$Revision: 1.1 $</tt>
  + * @version <tt>$Revision: 1.2 $</tt>
    * @author  <a href="mailto:[EMAIL PROTECTED]";>Jason Dillon</a>
    */
   public interface ServerConfig
  @@ -124,6 +124,27 @@
   
   
      /////////////////////////////////////////////////////////////////////////
  +   //                            Path Suffixes                            //
  +   /////////////////////////////////////////////////////////////////////////
  +
  +   String DATA_DIR_SUFFIX = "db";
  +   String TEMP_DIR_SUFFIX = "tmp";
  +   String LIBRARY_URL_SUFFIX = "lib/";
  +   String CONFIG_URL_SUFFIX = "conf/";
  +
  +
  +   /////////////////////////////////////////////////////////////////////////
  +   //                               Defaults                              //
  +   /////////////////////////////////////////////////////////////////////////
  +
  +   /** The default value for {@link #CONFIG_NAME}. */
  +   String DEFAULT_CONFIG_NAME = "default";
  +
  +   /** The default value for {@link #EXIT_ON_SHUTDOWN}. */
  +   boolean DEFAULT_EXIT_ON_SHUTDOWN = false;
  +
  +
  +   /////////////////////////////////////////////////////////////////////////
      //                         Typed Access Methods                        //
      /////////////////////////////////////////////////////////////////////////
   
  @@ -184,8 +205,8 @@
      URL getPatchURL();
      
      /**
  -    * Enable or disable exiting the JVM when {@link #shutdown} is called.
  -    * If enabled, then shutdown calls {@link #exit}.  If disabled, then
  +    * Enable or disable exiting the JVM when {@link Server#shutdown} is called.
  +    * If enabled, then shutdown calls {@link Server#exit}.  If disabled, then
       * only the shutdown hook will be run.
       *
       * @param flag    True to enable calling exit on shutdown.
  @@ -193,9 +214,7 @@
      void setExitOnShutdown(boolean flag);
   
       /**
  -     * Get the current value of the exit on shutdown flag.  Default value is
  -     * false, though it will be set to true when bootstrapped with 
  -     * {@link org.jboss.Main}.
  +     * Get the current value of the exit on shutdown flag.
        *
        * @return    The current value of the exit on shutdown flag.
        */
  
  
  
  1.2       +563 -22   jboss-system/src/main/org/jboss/system/server/ServerImpl.java
  
  Index: ServerImpl.java
  ===================================================================
  RCS file: 
/cvsroot/jboss/jboss-system/src/main/org/jboss/system/server/ServerImpl.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ServerImpl.java   22 Feb 2002 08:00:45 -0000      1.1
  +++ ServerImpl.java   24 Feb 2002 10:24:34 -0000      1.2
  @@ -9,40 +9,127 @@
   
   package org.jboss.system.server;
   
  +import java.io.File;
  +import java.io.FileFilter;
  +
  +import java.net.URL;
  +
  +import java.util.List;
  +import java.util.ArrayList;
  +import java.util.Iterator;
  +import java.util.Properties;
   import java.util.Map;
  +import java.util.HashMap;
  +import java.util.Date;
  +
  +import javax.management.MBeanServer;
  +import javax.management.MBeanServerFactory;
  +import javax.management.ObjectName;
  +import javax.management.MBeanException;
  +import javax.management.RuntimeMBeanException;
  +import javax.management.RuntimeErrorException;
  +import javax.management.RuntimeOperationsException;
  +import javax.management.ReflectionException;
  +
  +import org.jboss.Version;
  +
  +import org.jboss.logging.Logger;
  +
  +import org.jboss.system.ServiceLibraries;
  +import org.jboss.system.UnifiedClassLoader;
  +import org.jboss.system.MBeanClassLoader;
   
   /**
  - * The default (and probably only) {@link Server} implementation.
  + * The main container component of a JBoss server instance.
    *
  - * @version <tt>$Revision: 1.1 $</tt>
  - * @author  <a href="mailto:[EMAIL PROTECTED]";>Jason Dillon</a>
  + * @author <a href="mailto:[EMAIL PROTECTED]";>Marc Fleury</a>
  + * @author <a href="mailto:[EMAIL PROTECTED]";>Jason Dillon</a>
  + * @version $Revision: 1.2 $
    */
   public class ServerImpl
  -   implements Server
  +   implements ServerImplMBean
   {
  -   protected boolean started;
  -   protected ServerConfig config;
  +   /** 
  +    * Class logger.  We masqurade as Server for looks, but we log our
  +    * impl type too.
  +    */
  +   private static final Logger log = Logger.getLogger(Server.class);
  +   
  +   /** Container for version information. */
  +   private final Version version = Version.getInstance();
  +
  +   /** Package information for org.jboss */
  +   private final Package jbossPackage = Package.getPackage("org.jboss");
  +
  +   /** The basic configuration for the server. */
  +   private ServerConfigImpl config;
  +   
  +   /** The JMX MBeanServer which will serve as our communication bus. */
  +   private MBeanServer server;
  +
  +   /** The main deployer object name, replace with proxy once deployment moved to 
JBoss/System */
  +   private ObjectName mainDeployer;
  +
  +   /** When the server was started. */
  +   private Date startDate;
  +   
  +   /** Flag to indicate if we are started. */
  +   private boolean started;
  +
  +   /** The JVM shutdown hook */
  +   private ShutdownHook shutdownHook;
   
      /**
  -    * Required no-args constructor for {@link ServerLoader}.
  +    * No-arg constructor for {@link ServerLoader}.
       */
      public ServerImpl()
      {
         super();
      }
  -
  +   
      /**
       * Initialize the Server instance.
       *
  -    * @param props    The configuration properties for the server.
  +    * @param props     The configuration properties for the server.
  +    * @return          Typed server configuration object.
       *
       * @throws IllegalStateException    Already initialized.
       * @throws Exception                Failed to initialize.
       */
  -   public void init(Map props) throws IllegalStateException, Exception 
  +   public void init(final Properties props) throws IllegalStateException, Exception
      {
  -      System.out.println("Init: " + props);
  -      // config = new ServerConfig() {};
  +      if (props == null)
  +         throw new IllegalArgumentException("props is null");
  +      if (config != null)
  +         throw new IllegalStateException("already initialized");
  +
  +      // make sure our impl type is exposed
  +      log.debug("server type: " + getClass());
  +
  +      // Show what release this is...
  +      log.info("JBoss Release: " + jbossPackage.getImplementationTitle());
  +
  +      // Setup JBoss URL handlers
  +      String handlerPkgs = System.getProperty("java.protocol.handler.pkgs", null);
  +      if (handlerPkgs == null)
  +         handlerPkgs = "org.jboss.net.protocol";
  +      else
  +         handlerPkgs += ":org.jboss.net.protocol";
  +      System.setProperty("java.protocol.handler.pkgs", handlerPkgs );
  +
  +      // create a new config object from the give properties
  +      this.config = new ServerConfigImpl(props);
  +      log.debug("Using config: " + config);
  +
  +      // Log the basic configuration elements
  +      log.info("Config Name: " + config.getConfigName());
  +      log.info("Home Dir: " + config.getHomeDir());
  +      log.info("Install URL: " + config.getInstallURL());
  +      log.info("Configuration URL: " + config.getConfigURL());
  +      log.info("Library URL: " + config.getLibraryURL());
  +      log.info("Data Dir: " + config.getDataDir());
  +      log.info("Temporay Dir: " + config.getTempDir());
  +      log.info("Patch URL: " + config.getPatchURL());
      }
   
      /**
  @@ -55,8 +142,20 @@
       */
      public ServerConfig getConfig() throws IllegalStateException
      {
  +      if (config == null)
  +         throw new IllegalStateException("not initialized");
  +
         return config;
      }
  +   
  +   /**
  +    * Check if the server is started.
  +    *
  +    * @return   True if the server is started, else false.
  +    */
  +   public boolean isStarted() {
  +      return started;
  +   }
   
      /**
       * Start the Server instance.
  @@ -66,27 +165,469 @@
       */
      public void start() throws IllegalStateException, Exception 
      {
  -      System.out.println("Start");
  +      // make sure we are initialized
  +      getConfig();
  +
  +      // make sure we aren't started yet
  +      if (started)
  +         throw new IllegalStateException("already started");
  +
  +      // Deal with those pesky JMX throwables
  +      try {
  +         try
  +         {
  +            doStart();
  +         }
  +         catch (MBeanException e)
  +         {
  +            throw e.getTargetException();
  +         }
  +         catch (RuntimeMBeanException e)
  +         {
  +            throw e.getTargetException();
  +         }
  +         catch (RuntimeOperationsException e)
  +         {
  +            throw e.getTargetException();
  +         }
  +         catch (ReflectionException e)
  +         {
  +            throw e.getTargetException();
  +         }
  +         catch (RuntimeErrorException e)
  +         {
  +            throw e.getTargetError();
  +         }
  +      }
  +      catch (Throwable t)
  +      {
  +         log.error("start failed", t);
  +         if (t instanceof Exception)
  +            throw (Exception)t;
  +         if (t instanceof Error)
  +            throw (Error)t;
  +         
  +         throw new org.jboss.util.UnexpectedThrowable(t);
  +      }
  +   }
  +
  +   /** Actually does the starting... */
  +   private void doStart() throws Exception 
  +   {
  +      // remeber when we we started
  +      startDate = new Date();
  +      log.info("Starting General Purpose Architecture (GPA)...");
  +      
  +      // Create the MBeanServer
  +      server = MBeanServerFactory.createMBeanServer("jboss");
  +      log.debug("Created MBeanServer: " + server);
  +      
  +      // Register server components
  +      server.registerMBean(this, ServerImplMBean.OBJECT_NAME);
  +      server.registerMBean(config, ServerConfigImplMBean.OBJECT_NAME);
  +      
  +      // Initialize the MBean libraries repository
  +      server.registerMBean(ServiceLibraries.getLibraries(), null);
  +      
  +      // Initialize spine boot libraries
  +      initBootLibraries();
  +      
  +      // Create MBeanClassLoader for the base system
  +      ObjectName loaderName =
  +         new ObjectName("jboss.system", "service", "ServiceClassLoader");
  +      
  +      MBeanClassLoader mcl = new MBeanClassLoader(loaderName);
  +      server.registerMBean(mcl, loaderName);
  +      log.debug("Registered service classloader: " + loaderName);
  +      
  +      // Set ServiceClassLoader as classloader for the construction of
  +      // the basic system
  +      Thread.currentThread().setContextClassLoader(mcl);
  +      
  +      // Setup logging
  +      server.createMBean("org.jboss.logging.Log4jService", null, loaderName);
  +      log.debug("Logging has been initialized");
  +      
  +      // General Purpose Architecture information
  +      server.createMBean("org.jboss.system.server.ServerInfo", null, loaderName);
  +      
  +      // Service Controller
  +      ObjectName controllerName =
  +         server.createMBean("org.jboss.system.ServiceController", null, 
loaderName).getObjectName();
  +      log.debug("Registered service controller: " + controllerName);
  +      
  +      // Install the shutdown hook
  +      shutdownHook = new ShutdownHook(controllerName);
  +      try
  +      {
  +         Runtime.getRuntime().addShutdownHook(shutdownHook);
  +         log.debug("Shutdown hook added");
  +      }
  +      catch (Exception e)
  +      {
  +         log.warn("Failed to add shutdown hook", e);
  +      }
  +      
  +      // Main Deployer
  +      mainDeployer =
  +         server.createMBean("org.jboss.deployment.MainDeployer", null, 
loaderName).getObjectName();
  +      
  +      // Initialize the MainDeployer
  +      server.invoke(mainDeployer, "create", new Object[0], new String[0]);
  +      
  +      // SAR Deployer
  +      server.createMBean("org.jboss.deployment.SARDeployer", null, loaderName);
  +
  +      log.info("Core system initialized");
  +
  +      // TODO: Split up init (ie. create) from start ops so we can expose more 
control
  +      //       to embeded clients.
  +
  +      // Ok, now do a first deploy of JBoss' jboss-service.xml
  +      server.invoke(mainDeployer,
  +                    "deploy",
  +                    new Object[] { config.getConfigURL() + "jboss-service.xml" },
  +                    new String[] { "java.lang.String" });
  +
  +      // Start the main deployer thread
  +      server.invoke(mainDeployer, "start", new Object[0], new String[0]);
  +      
  +      // Calculate how long it took
  +      long lapsedTime = System.currentTimeMillis() - startDate.getTime();
  +      long minutes = lapsedTime / 60000;
  +      long seconds = (lapsedTime - 60000 * minutes) / 1000;
  +      long milliseconds = (lapsedTime - 60000 * minutes - 1000 * seconds);
  +
  +      // Tell the world how fast it was =)
  +      log.info("JBoss (MX MicroKernel) [" + jbossPackage.getImplementationVersion() 
+               
  +               "] Started in " + minutes  + "m:" + seconds  + "s:" + milliseconds 
+"ms");
  +
  +      started = true;
      }
   
      /**
  -    * Shutdown the Server instance.
  +    * Initialize the boot libraries.
  +    */
  +   private void initBootLibraries() throws Exception
  +   {
  +      boolean debug = log.isDebugEnabled();
  +      
  +      // Build the list of URL for the spine to boot
  +      List list = new ArrayList();
  +      
  +      // Add the patch URL.  If the url protocol is file, then
  +      // add the contents of the directory it points to
  +      URL patchURL = config.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 FileFilter()
  +               {
  +                  public boolean accept(File file)
  +                  {
  +                     String name = file.getName().toLowerCase();
  +                     return name.endsWith(".jar") || name.endsWith(".zip");
  +                  }
  +               });
  +               
  +               for (int j = 0; jars != null && j < jars.length; j++)
  +               {
  +                  list.add(jars[j].getCanonicalFile().toURL());
  +               }
  +            }
  +         }
  +         else
  +         {
  +            list.add(patchURL);
  +         }
  +      }
  +      
  +      // Add configuration directory to be able to load config files as resources
  +      list.add(config.getConfigURL());
  +      
  +      // Not needed, ServerImpl will have the basics on its classpath from 
ServerLoader
  +      // may want to bring this back at some point if we want to have reloadable 
core
  +      // components...
  +
  +      // URL libraryURL = config.getLibraryURL();
  +      // list.add(new URL(libraryURL, "jboss-spine.jar"));
  +
  +      // Create loaders for each URL
  +      Iterator iter = list.iterator();
  +      while (iter.hasNext())
  +      {
  +         URL url = (URL)iter.next();
  +         if (debug)
  +         {
  +            log.debug("Creating loader for URL: " + url);
  +         }
  +         
  +         // Construction of URLClassLoader also registers with ServiceLibraries
  +         // Should probably remove this "side-effect" and make this more explicit
  +         
  +         // This is a boot URL, so key it on itself.
  +         UnifiedClassLoader loader = new UnifiedClassLoader(url);
  +      }
  +   }
  +   
  +   /**
  +    * Shutdown the Server instance and run shutdown hooks.  
  +    *
  +    * <p>If the exit on shutdown flag is true, then {@link #exit} 
  +    *    is called, else only the shutdown hook is run.
       *
       * @throws IllegalStateException    No started.
  -    * @throws Exception                Failed to shutdown.
       */
  -   public void shutdown() throws IllegalStateException, Exception 
  +   public void shutdown() throws IllegalStateException
      {
  -      System.out.println("shutdown");
  -   }
  +      if (!started)
  +         throw new IllegalStateException("not started");
   
  +      final ServerImpl server = this;
  +      
  +      log.info("Shutting down");
  +      
  +      boolean exitOnShutdown = config.getExitOnShutdown();
  +      if (log.isDebugEnabled())
  +      {
  +         log.debug("exitOnShutdown: " + exitOnShutdown);
  +      }
  +      
  +      if (exitOnShutdown)
  +      {
  +         server.exit(0);
  +      }
  +      else
  +      {
  +         // start in new thread to give positive
  +         // feedback to requesting client of success.
  +         new Thread()
  +         {
  +            public void run()
  +            {
  +               // just run the hook, don't call System.exit, as we may
  +               // be embeded in a vm that would not like that very much
  +               shutdownHook.run();
  +            }
  +         }.start();
  +      }
  +   }
  +   
      /**
  -    * Check if the server is started.
  +    * Shutdown the server, the JVM and run shutdown hooks.
       *
  -    * @return   True if the server is started, else false.
  +    * @param exitcode   The exit code returned to the operating system.
       */
  -   public boolean isStarted()
  +   public void exit(final int exitcode)
      {
  -      return started;
  +      // start in new thread so that we might have a chance to give positive
  +      // feed back to requesting client of success.
  +      new Thread()
  +      {
  +         public void run()
  +         {
  +            log.info("Shutting down the JVM now!");
  +            Runtime.getRuntime().exit(exitcode);
  +         }
  +      }.start();
  +   }
  +   
  +   /**
  +    * Shutdown the server, the JVM and run shutdown hooks.  Exits with
  +    * code 1.
  +    */
  +   public void exit()
  +   {
  +      exit(1);
  +   }
  +   
  +   /**
  +    * Forcibly terminates the currently running Java virtual machine.
  +    *
  +    * @param exitcode   The exit code returned to the operating system.
  +    */
  +   public void halt(final int exitcode)
  +   {
  +      // start in new thread so that we might have a chance to give positive
  +      // feed back to requesting client of success.
  +      new Thread()
  +      {
  +         public void run()
  +         {
  +            System.err.println("Halting the system now!");
  +            Runtime.getRuntime().halt(exitcode);
  +         }
  +      }.start();
  +   }
  +   
  +   /**
  +    * Forcibly terminates the currently running Java virtual machine.
  +    * Exits with code 1.
  +    */
  +   public void halt()
  +   {
  +      halt(1);
  +   }
  +   
  +   
  +   ///////////////////////////////////////////////////////////////////////////
  +   //                            Runtime Access                             //
  +   ///////////////////////////////////////////////////////////////////////////
  +   
  +   /** A simple helper used to log the Runtime memory information. */ 
  +   private void logMemoryUsage(final Runtime rt)
  +   {
  +      log.info("Total/free memory: " + rt.totalMemory() + "/" + rt.freeMemory());
  +   }
  +   
  +   public void runGarbageCollector()
  +   {
  +      Runtime rt = Runtime.getRuntime();
  +      
  +      logMemoryUsage(rt);
  +      rt.gc();
  +      log.info("Hinted to the JVM to run garbage collection");
  +      logMemoryUsage(rt);
  +   }
  +   
  +   public void runFinalization()
  +   {
  +      Runtime.getRuntime().runFinalization();
  +      log.info("Hinted to the JVM to run any pending object finalizations");
  +   }
  +   
  +   /**
  +    * Enable or disable tracing method calls at the Runtime level.
  +    */
  +   public void traceMethodCalls(final Boolean flag)
  +   {
  +      Runtime.getRuntime().traceMethodCalls(flag.booleanValue());
  +   }
  +   
  +   /**
  +    * Enable or disable tracing instructions the Runtime level.
  +    */
  +   public void traceInstructions(final Boolean flag)
  +   {
  +      Runtime.getRuntime().traceInstructions(flag.booleanValue());
  +   }
  +   
  +   
  +   ///////////////////////////////////////////////////////////////////////////
  +   //                          Server Information                           //
  +   ///////////////////////////////////////////////////////////////////////////
  +   
  +   public Date getStartDate()
  +   {
  +      return startDate;
  +   }
  +   
  +   public Long getTotalMemory()
  +   {
  +      return new Long(Runtime.getRuntime().totalMemory());
  +   }
  +   
  +   public Long getFreeMemory()
  +   {
  +      return new Long(Runtime.getRuntime().freeMemory());
  +   }
  +   
  +   public Long getMaxMemory()
  +   {
  +      // Uncomment when JDK 1.4 is the base JVM
  +      // return new Long(Runtime.getRuntime().maxMemory());
  +      return new Long(-1);
  +   }
  +   
  +   public String getVersion()
  +   {
  +      return version.toString();
  +   }
  +   
  +   public String getVersionName()
  +   {
  +      return version.getName();
  +   }
  +   
  +   public String getBuildNumber()
  +   {
  +      return version.getBuildNumber();
  +   }
  +   
  +   public String getBuildID()
  +   {
  +      return version.getBuildID();
  +   }
  +   
  +   public String getBuildDate()
  +   {
  +      return version.getBuildDate();
  +   }
  +   
  +   
  +   ///////////////////////////////////////////////////////////////////////////
  +   //                             Shutdown Hook                             //
  +   ///////////////////////////////////////////////////////////////////////////
  +   
  +   private class ShutdownHook
  +      extends Thread
  +   {
  +      /** The ServiceController which we will ask to shut things down with. */
  +      private ObjectName contollerName;
  +      
  +      public ShutdownHook(final ObjectName contollerName)
  +      {
  +         super("JBoss Shutdown Hook");
  +         
  +         this.contollerName = contollerName;
  +      }
  +      
  +      public void run()
  +      {
  +         log.info("Shutting down all services");
  +         System.out.println("Shutting down");
  +         
  +         // Make sure all services are down properly
  +         shutdownServices();
  +         
  +         log.info("Shutdown complete");
  +         System.out.println("Shutdown complete");
  +      }
  +      
  +      /**
  +       * 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
  +            server.invoke(contollerName,
  +                          "shutdown",
  +                          new Object[0],
  +                          new String[0]);
  +         }
  +         catch (MBeanException e)
  +         {
  +            log.error("failed to shutdown", e.getTargetException());
  +         }
  +         catch (RuntimeMBeanException e)
  +         {
  +            log.error("failed to shutdown", e.getTargetException());
  +         }
  +         catch (Exception e)
  +         {
  +            log.error("failed to shutdown", e);
  +         }
  +      }
      }
   }
  
  
  
  1.2       +100 -60   jboss-system/src/main/org/jboss/system/server/ServerLoader.java
  
  Index: ServerLoader.java
  ===================================================================
  RCS file: 
/cvsroot/jboss/jboss-system/src/main/org/jboss/system/server/ServerLoader.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ServerLoader.java 22 Feb 2002 08:00:45 -0000      1.1
  +++ ServerLoader.java 24 Feb 2002 10:24:34 -0000      1.2
  @@ -9,7 +9,7 @@
   
   package org.jboss.system.server;
   
  -import java.util.Map;
  +import java.util.Properties;
   import java.util.StringTokenizer;
   import java.util.List;
   import java.util.LinkedList;
  @@ -24,18 +24,19 @@
    * <p>Basic usage is something like this:
    * <pre>
    *    // setup the basic server config properties
  - *    Map props = new HashMap();
  + *    Properties props = new Properties(System.getProperties());
    *    props.put(ServerConfig.LIBRARY_URL, "http://myserver.com/myjboss/lib/";);
    *    // set some more properties
    *
    *    // create a new loader to do the dirty work
    *    ServerLoader loader = new ServerLoader(props);
    *
  - *    // add the jaxp library to use
  - *    loader.addBootLibrary("crimson.jar");
  + *    // add the jaxp & jmx library to use
  + *    loader.addLibrary("crimson.jar");
  + *    loader.addLibrary("jmxri.jar");
    *
    *    // load and initialize the server instance
  - *    Server server = loader.load();
  + *    Server server = loader.load(Thread.currentThread().getContextClassLoader());
    *    server.init(props);
    *
    *    // start up the server
  @@ -48,28 +49,26 @@
    *    server.shutdown();
    * </pre>
    *
  - * @version <tt>$Revision: 1.1 $</tt>
  + * @version <tt>$Revision: 1.2 $</tt>
    * @author  <a href="mailto:[EMAIL PROTECTED]";>Jason Dillon</a>
    */
   public class ServerLoader
   {
      /** 
       * The default list of boot libraries.  Does not include
  -    * the JAXP impl, users of this class should append the 
  -    * proper jar to this list.
  +    * the JAXP or JMX impl, users of this class should add the 
  +    * proper libraries.
       */
  -   public static final String DEFUALT_BOOT_LIBRARY_LIST = 
"jaxp.jar,jmxri.jar,jboss-common.jar,jboss-system.jar";
  +   public static final String DEFUALT_BOOT_LIBRARY_LIST = 
  +      "jaxp.jar,log4j.jar,jboss-common.jar,jboss-system.jar";
   
      /** The default server type. */
      public static final String DEFAULT_SERVER_TYPE = 
"org.jboss.system.server.ServerImpl";
   
      /** 
  -    * Map of configuration properties.
  -    *
  -    * <p>Required unset values will be read from System properties
  -    *    else defaults will be used if applicable.
  +    * Configuration properties.
       */
  -   protected Map props;
  +   protected Properties props;
   
      /**
       * The URL where libraries are read from.
  @@ -77,16 +76,15 @@
      protected URL libraryURL;
   
      /**
  -    * A list of extra library file names to load from the library 
  -    * URL in addition to the list specified in the configuration
  -    * properties.
  +    * A list of extra URLs to add to the classpath when loading
  +    * the server.
       */
  -   protected List extraBootLibraries = new LinkedList();
  +   protected List extraClasspath = new LinkedList();
   
      /**
       * Construct a <tt>ServerLoader</tt>.  The properties map
  -    * passed in must contain a value for {@link ServerConfig.INSTALL_URL}
  -    * or {@link ServerConfig.LIBRARY_URL} at the very minimum for the 
  +    * passed in must contain a value for {@link ServerConfig#INSTALL_URL}
  +    * or {@link ServerConfig#LIBRARY_URL} at the very minimum for the 
       * loader to function.  Other values may be required by the server 
       * implementation as well.
       *
  @@ -94,28 +92,36 @@
       *
       * @throws Exception    Invalid configuration
       */
  -   public ServerLoader(final Map props) throws Exception
  +   public ServerLoader(final Properties props) throws Exception
      {
         if (props == null)
            throw new IllegalArgumentException("props is null");
   
         this.props = props;
   
  -      libraryURL = getURL(ServerConfig.LIBRARY_URL, null);
  +      //
  +      // NOTE:
  +      //
  +      // The following is a tiny duplication of what a ServerConfig impl
  +      // does.  It was seperated to free the loader layer from the size
  +      // of a full impl.  Make sure changes are sync'd when reving SC
  +      //
  +
  +      libraryURL = getURL(ServerConfig.LIBRARY_URL);
   
         if (libraryURL == null) {
            // must have install url, or we can't continue
  -         URL installURL = getURL(ServerConfig.INSTALL_URL, null);
  +         URL installURL = getURL(ServerConfig.INSTALL_URL);
            if (installURL == null)
               throw new Exception("Missing configuration value for: " + 
ServerConfig.INSTALL_URL);
   
            // need libraray url to make boot urls list
  -         libraryURL = new URL(installURL, "lib");
  +         libraryURL = new URL(installURL, ServerConfig.LIBRARY_URL_SUFFIX);
         }
      }
   
      /**
  -    * Add an extra boot library to the end of list of libraries
  +    * Add an extra library to the end of list of libraries
       * which will be loaded from the library URL when loading
       * the Server class.
       *
  @@ -123,78 +129,112 @@
       *
       * @throws MalformedURLException   Could not generate URL from library URL + 
filename
       */
  -   public void addBootLibrary(String filename) throws MalformedURLException
  +   public void addLibrary(final String filename) throws MalformedURLException
      {
         if (filename == null)
            throw new IllegalArgumentException("filename is null");
   
  -      extraBootLibraries.add(new URL(libraryURL, filename));
  +      extraClasspath.add(new URL(libraryURL, filename));
      }
   
      /**
  -    * Load a {@link Server} instance.
  +    * Add a list of comma seperated library file names.
       *
  -    * @return    An uninitialized (and unstarted) Server instance.
  +    * @param filenames   A list of comma seperated filenames (with no directory 
parts)
       *
  -    * @throws Exception   Failed to load or create Server instance.
  +    * @throws MalformedURLException   Could not generate URL from library URL + 
filename
       */
  -   public Server load() throws Exception
  +   public void addLibraries(final String filenames) throws MalformedURLException
      {
  -      // get the boot lib list
  -      URL[] urls = getBootLibraryList(libraryURL);
  -      URLClassLoader classLoader = 
  -         new URLClassLoader(urls, Thread.currentThread().getContextClassLoader());
  -
  -      // construct a new Server instance
  -      String typename = readValue(ServerConfig.SERVER_TYPE, DEFAULT_SERVER_TYPE);
  -      Server server = createServer(typename, classLoader);
  +      if (filenames == null)
  +         throw new IllegalArgumentException("filenames is null");
   
  -      // thats all folks, have fun
  -      return server;
  +      StringTokenizer stok = new StringTokenizer(filenames, ",");
  +      while (stok.hasMoreElements()) {
  +         addLibrary(stok.nextToken().trim());
  +      }
  +   }
  +
  +   /**
  +    * Add an extra URL to the classpath used to load the server.
  +    *
  +    * @param url    A URL to add to the classpath.
  +    */
  +   public void addURL(final URL url) 
  +   {
  +      if (url == null)
  +         throw new IllegalArgumentException("url is null");
  +
  +      extraClasspath.add(url);
      }
   
      /**
       * Get a URL from configuration or system properties.
       */
  -   protected URL getURL(final String name, final URL defaultValue) throws 
MalformedURLException
  +   protected URL getURL(final String name) throws MalformedURLException
      {
  -      String value = readValue(name, null);
  -      if (value != null)
  +      String value = props.getProperty(name, null);
  +      if (value != null) {
  +         if (!value.endsWith("/")) value += "/";
            return new URL(value);
  -      return defaultValue;
  +      }
  +      return null;
      }
   
      /**
       * Retruns an array of URLs which will be used to load the
       * core system and construct a new Server object instance.
       */
  -   protected URL[] getBootLibraryList(final URL libraryURL) throws 
MalformedURLException
  +   protected URL[] getBootClasspath() throws MalformedURLException
      {
  -      String value = readValue(ServerConfig.BOOT_LIBRARY_LIST, 
DEFUALT_BOOT_LIBRARY_LIST);
  -
         List list = new LinkedList();
  -      StringTokenizer stok = new StringTokenizer(value.toString(), ",");
  +
  +      // prepend users classpath to allow for overrides
  +      list.addAll(extraClasspath);
  +
  +      String value = props.getProperty(ServerConfig.BOOT_LIBRARY_LIST, 
DEFUALT_BOOT_LIBRARY_LIST);
  +
  +      StringTokenizer stok = new StringTokenizer(value, ",");
         while (stok.hasMoreElements()) {
  -         URL url = new URL(libraryURL, stok.nextToken());
  +         URL url = new URL(libraryURL, stok.nextToken().trim());
            list.add(url);
         }
  -      
  -      list.addAll(extraBootLibraries);
  -      System.out.println(list);
   
         return (URL[])list.toArray(new URL[list.size()]);
      }
   
      /**
  -    * Read a value from configuration.  Consults System properties
  -    * if the key is not in our own config. 
  +    * Load a {@link Server} instance.
  +    *
  +    * @parent    The parent of any class loader created during boot.
  +    * @return    An uninitialized (and unstarted) Server instance.
  +    *
  +    * @throws Exception   Failed to load or create Server instance.
       */
  -   protected String readValue(final String name, String defaultValue)
  +   public Server load(final ClassLoader parent) throws Exception
      {
  -      String value = (String)props.get(name);
  -      if (value == null)
  -         return value = System.getProperty(name, defaultValue);
  -      return value;
  +      Server server;
  +
  +      // Save the current loader so we can restore it.
  +      ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
  +                     
  +      try {
  +         // get the boot lib list
  +         URL[] urls = getBootClasspath();
  +         URLClassLoader classLoader = new URLClassLoader(urls, parent);
  +         Thread.currentThread().setContextClassLoader(classLoader);
  +
  +         // construct a new Server instance
  +         String typename = props.getProperty(ServerConfig.SERVER_TYPE, 
DEFAULT_SERVER_TYPE);
  +         server = createServer(typename, classLoader);
  +      }
  +      finally {
  +         // Restore the previous classloader
  +         Thread.currentThread().setContextClassLoader(oldClassLoader);
  +      }
  +
  +      // thats all folks, have fun
  +      return server;
      }
   
      /**
  
  
  
  1.1                  
jboss-system/src/main/org/jboss/system/server/ServerConfigImpl.java
  
  Index: ServerConfigImpl.java
  ===================================================================
  /***************************************
   *                                     *
   *  JBoss: The OpenSource J2EE WebOS   *
   *                                     *
   *  Distributable under LGPL license.  *
   *  See terms of license at gnu.org.   *
   *                                     *
   ***************************************/
  
  package org.jboss.system.server;
  
  import java.util.Properties;
  
  import java.io.File;
  
  import java.net.URL;
  import java.net.MalformedURLException;
  
  import org.jboss.util.NestedRuntimeException;
  import org.jboss.util.Null;
  import org.jboss.util.MuBoolean;
  
  /**
   * A container for the basic configuration elements required to create
   * a Server instance.
   *
   * <p>MalformedURLException are rethrown as NestedRuntimeExceptions, so that
   *    code that needs to access these values does not have to directly 
   *    worry about problems with lazy construction of final URL values.
   *      
   * @author <a href="mailto:[EMAIL PROTECTED]";>Jason Dillon</a>
   * @version $Revision: 1.1 $
   */
  public class ServerConfigImpl
     implements ServerConfigImplMBean
  {
     /** The configuration properties to pull data from. */
     private final Properties props;
  
     /** The local home directory for the server. */
     private final File homeDir;
  
     /** The directory for server temporay files. */
     private File tempDir;
  
     /** The directory for local data files. */
     private File dataDir;
     
     /** The base installation URL, used to construct other URLs. */
     private final URL installURL;
  
     /** The configuration name to use. */
     private String configName;
     
     /** The URL where configuration files will be found. */
     private URL configURL;
  
     /** The base URL where library files are. */
     private URL libraryURL;
     
     /** 
      * The base URL where patch files will be loaded from. This is 
      * typed as an Object to allow its value to contain Null.VALUE
      * or a URL.  If value is Null.VALUE then we have determined
      * that there is no user configuration for this value and it will
      * be passed back as null to the requesting client.
      */
     private Object patchURL;
     
     /** Exit on shutdown flag. */
     private MuBoolean exitOnShutdown;
  
     /** 
      * Construct a new <tt>ServerConfigImpl</tt> instance.
      *
      * @param props    Configuration properties.
      *
      * @throws Exception    Missing or invalid configuration.
      */
     public ServerConfigImpl(final Properties props) throws Exception
     {
        this.props = props;
  
        // Must home DIR and install URL
        homeDir = getFile(ServerConfig.HOME_DIR);
        if (homeDir == null)
           throw new Exception("Missing configuration value for: " + 
ServerConfig.HOME_DIR);
  
        installURL = getURL(ServerConfig.INSTALL_URL);
        if (installURL == null)
           throw new Exception("Missing configuration value for: " + 
ServerConfig.INSTALL_URL);
     }
  
     /**
      * Get a URL from configuration.
      */
     private URL getURL(final String name) throws MalformedURLException
     {
        String value = props.getProperty(name, null);
        if (value != null) {
           if (!value.endsWith("/")) value += "/";
           return new URL(value);
        }
  
        return null;
     }
  
     /**
      * Get a File from configuration.
      */
     private File getFile(final String name)
     {
        String value = props.getProperty(name, null);
        if (value != null) {
           return new File(value);
        }
  
        return null;
     }
  
  
     /////////////////////////////////////////////////////////////////////////
     //                             Typed Access                            //
     /////////////////////////////////////////////////////////////////////////
  
     public String getConfigName() {
        if (configName == null) {
           configName = props.getProperty(ServerConfig.CONFIG_NAME, 
ServerConfig.DEFAULT_CONFIG_NAME);
        }
        return configName;
     }
  
     public File getHomeDir() {
        // this is preset in constructor
        return homeDir;
     }
  
     public File getTempDir() { 
        if (tempDir == null) {
           tempDir = getFile(ServerConfig.TEMP_DIR);
           if (tempDir == null) {
              tempDir = new File(homeDir, ServerConfig.TEMP_DIR_SUFFIX);
           }
        }
        
        return tempDir;
     }
  
     public File getDataDir() {
        if (dataDir == null) {
           dataDir = getFile(ServerConfig.DATA_DIR);
           if (dataDir == null) {
              dataDir = new File(homeDir, ServerConfig.DATA_DIR_SUFFIX);
           }
        }
        
        return dataDir;
     }
     
     public URL getInstallURL() {
        // this is preset in constructor
        return installURL;
     }
     
     public URL getLibraryURL() {
        if (libraryURL == null) {
           try {
              libraryURL = getURL(ServerConfig.LIBRARY_URL);
              if (libraryURL == null) {
                 libraryURL = new URL(installURL, ServerConfig.LIBRARY_URL_SUFFIX);
              }
           }
           catch (MalformedURLException e) {
              throw new NestedRuntimeException(e);
           }
        }
        return libraryURL;
     }
  
     public URL getConfigURL() {
        if (configURL == null) {
           try {
              // get the base url
              configURL = getURL(ServerConfig.CONFIG_URL);
              if (configURL == null) {
                 configURL = new URL(installURL, ServerConfig.CONFIG_URL_SUFFIX);
              }
  
              // tack on config name 
              String temp = getConfigName();
              if (!temp.endsWith("/")) temp += "/";
              configURL = new URL(configURL, temp);
           }
           catch (MalformedURLException e) {
              throw new NestedRuntimeException(e);
           }
        }
        return configURL;
     }
     
     public URL getPatchURL() {
        if (patchURL == null) {
           try {
              patchURL = getURL(ServerConfig.PATCH_URL);
              if (patchURL == null) {
                 patchURL = Null.VALUE;
              }
           }
           catch (MalformedURLException e) {
              throw new NestedRuntimeException(e);
           }
        }
  
        if (patchURL == Null.VALUE)
           return null;
  
        return (URL)patchURL;
     }
  
     public void setExitOnShutdown(final boolean flag) {
        if (exitOnShutdown == null) {
           exitOnShutdown = new MuBoolean(flag);
        }
        else {
           exitOnShutdown.set(flag);
        }
     }
  
     public boolean getExitOnShutdown() {
        if (exitOnShutdown == null) {
           String value = props.getProperty(ServerConfig.EXIT_ON_SHUTDOWN, null);
           if (value == null) {
              exitOnShutdown = new MuBoolean(ServerConfig.DEFAULT_EXIT_ON_SHUTDOWN);
           }
           else {
              exitOnShutdown = new MuBoolean(value);
           }
        }
  
        return exitOnShutdown.get();
     }
  }
  
  
  
  1.1                  
jboss-system/src/main/org/jboss/system/server/ServerConfigImplMBean.java
  
  Index: ServerConfigImplMBean.java
  ===================================================================
  /*
   * JBoss, the OpenSource J2EE webOS
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  
  package org.jboss.system.server;
  
  import javax.management.ObjectName;
  
  import org.jboss.util.jmx.ObjectNameFactory;
  
  /**
   * The JMX MBean interface for the <tt>ServerConfigImpl</tt> component.
   *      
   * @author <a href="mailto:[EMAIL PROTECTED]";>Jason Dillon</a>
   * @version $Revision: 1.1 $
   */
  public interface ServerConfigImplMBean
     extends ServerConfig
  {
     /** The default object name. */
     ObjectName OBJECT_NAME = 
ObjectNameFactory.create("jboss.system:type=ServerConfig");
  }
  
  
  
  1.1                  
jboss-system/src/main/org/jboss/system/server/ServerImplMBean.java
  
  Index: ServerImplMBean.java
  ===================================================================
  /***************************************
   *                                     *
   *  JBoss: The OpenSource J2EE WebOS   *
   *                                     *
   *  Distributable under LGPL license.  *
   *  See terms of license at gnu.org.   *
   *                                     *
   ***************************************/
  
  package org.jboss.system.server;
  
  import java.util.Date;
  
  import javax.management.ObjectName;
  
  import org.jboss.util.jmx.ObjectNameFactory;
  
  /**
   * The JMX MBean interface for the <tt>ServerImpl</tt> component.
   *      
   * @author <a href="mailto:[EMAIL PROTECTED]";>Jason Dillon</a>
   * @version $Revision: 1.1 $
   */
  public interface ServerImplMBean
     extends Server
  {
     /** The default JMX object name for this MBean. */
     ObjectName OBJECT_NAME = ObjectNameFactory.create("jboss.system:type=Server");
     
     /**
      * Shutdown the Server instance and run shutdown hooks.  
      *
      * <p>If the exit on shutdown flag is true, then {@link exit} 
      *    is called, else only the shutdown hook is run.
      *
      * @throws IllegalStateException    No started.
      */
     void shutdown() throws IllegalStateException;
  
     /**
      * Shutdown the server, the JVM and run shutdown hooks.
      *
      * @param exitcode   The exit code returned to the operating system.
      */
     void exit(int exitcode);
  
     /**
      * Shutdown the server, the JVM and run shutdown hooks. Exits with 
      * code 1. 
      */
     void exit();
     
     /** 
      * Forcibly terminates the currently running Java virtual machine.
      *
      * @param exitcode   The exit code returned to the operating system.
      */
     void halt(int exitcode);
  
     /** 
      * Forcibly terminates the currently running Java virtual machine. 
      * Exits with code 1. 
      */
     void halt();
  
  
     ///////////////////////////////////////////////////////////////////////////
     //                            Runtime Access                             //
     ///////////////////////////////////////////////////////////////////////////
  
     /**
      * Hint to the JVM to run the garbage collector.
      */
     void runGarbageCollector();
  
     /**
      * Hint to the JVM to run any pending object finailizations.
      */
     void runFinalization();
  
     /**
      * Enable or disable tracing method calls at the Runtime level.
      */
     void traceMethodCalls(Boolean flag);
     
     /**
      * Enable or disable tracing instructions the Runtime level.
      */
     void traceInstructions(Boolean flag);
     
     
     ///////////////////////////////////////////////////////////////////////////
     //                          Server Information                           //
     ///////////////////////////////////////////////////////////////////////////
  
     Date getStartDate();
  
     Long getTotalMemory();
     
     Long getFreeMemory();
  
     Long getMaxMemory();
     
     String getVersion();
  
     String getVersionName();
  
     String getBuildNumber();
  
     String getBuildID();
  
     String getBuildDate();
  }
  
  
  
  1.1                  jboss-system/src/main/org/jboss/system/server/ServerInfo.java
  
  Index: ServerInfo.java
  ===================================================================
  /***************************************
   *                                     *
   *  JBoss: The OpenSource J2EE WebOS   *
   *                                     *
   *  Distributable under LGPL license.  *
   *  See terms of license at gnu.org.   *
   *                                     *
   ***************************************/
  
  package org.jboss.system.server;
  
  import java.util.Enumeration;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.HashMap;
  
  import javax.management.ObjectName;
  import javax.management.MBeanServer;
  import javax.management.MBeanRegistration;
  
  import org.jboss.logging.Logger;
  
  import org.jboss.system.ServiceLibraries;
  
  /**
   * An MBean that provides a rich view of system information for the JBoss
   * server in which it is deployed.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Rickard �berg</a>
   * @author <a href="mailto:[EMAIL PROTECTED]";>Scott Stark</a>
   * @author <a href="mailto:[EMAIL PROTECTED]";>Hiram Chirino</a>
   * @author <a href="mailto:[EMAIL PROTECTED]";>Jason Dillon</a>
   * @author <a href="mailto:[EMAIL PROTECTED]";>Marc Fleury</a>
   * @version $Revision: 1.1 $
   */
  public class ServerInfo
     implements ServerInfoMBean, MBeanRegistration
  {
     /** Class logger. */
     private static final Logger log = Logger.getLogger(ServerInfo.class);
     
     /** The cached host name for the server. */
     private String hostName;
     
     /** The cached host address for the server. */
     private String hostAddress;
     
     
     ///////////////////////////////////////////////////////////////////////////
     //                               JMX Hooks                               //
     ///////////////////////////////////////////////////////////////////////////
     
     public ObjectName preRegister(MBeanServer server, ObjectName name)
        throws Exception
     {
        // Dump out basic JVM & OS info as INFO priority msgs
        log.info("Java version: " +
        System.getProperty("java.version") + "," +
        System.getProperty("java.vendor"));
        
        log.info("Java VM: " +
        System.getProperty("java.vm.name") + " " +
        System.getProperty("java.vm.version") + "," +
        System.getProperty("java.vm.vendor"));
        
        log.info("OS-System: " +
        System.getProperty("os.name") + " " +
        System.getProperty("os.version") + "," +
        System.getProperty("os.arch"));
        
        // Dump out the entire system properties if debug is enabled
        if (log.isDebugEnabled())
        {
           log.debug("Full System Properties Dump");
           Enumeration names = System.getProperties().propertyNames();
           while (names.hasMoreElements())
           {
              String pname = (String)names.nextElement();
              log.debug("    " + pname + ": " + System.getProperty(pname));
           }
        }
        
        return name == null ? OBJECT_NAME : name;
     }
     
     public void postRegister(Boolean registrationDone)
     {
        // empty
     }
     
     public void preDeregister() throws Exception
     {
        // empty
     }
     
     public void postDeregister()
     {
        // empty
     }
     
     
     ///////////////////////////////////////////////////////////////////////////
     //                            Server Information                         //
     ///////////////////////////////////////////////////////////////////////////
     
     public String getHostName()
     {
        if (hostName == null)
        {
           try
           {
              hostName = java.net.InetAddress.getLocalHost().getHostName();
           }
           catch (java.net.UnknownHostException e)
           {
              log.error("Error looking up local hostname", e);
              hostName = "<unknown>";
           }
        }
        
        return hostName;
     }
     
     public String getHostAddress()
     {
        if (hostAddress == null)
        {
           try
           {
              hostAddress = java.net.InetAddress.getLocalHost().getHostAddress();
           }
           catch (java.net.UnknownHostException e)
           {
              log.error("Error looking up local address", e);
              hostAddress = "<unknown>";
           }
        }
        
        return hostAddress;
     }
  
     /** Return the total memory and free memory from Runtime
      */
     public String listMemoryUsage()
     {
        String rc= "<P><B>Total Memory: </B>" +
        (Runtime.getRuntime().totalMemory()) +
        " </P>" + "<P><B>Free Memory: </B>" +
        (Runtime.getRuntime().freeMemory()) + " </P>";
        return rc;
     }
  
     /** Return a listing of the active threads and thread groups.
      */
     public String listThreadDump()
     {
        // Get the root thread group
        ThreadGroup root= Thread.currentThread().getThreadGroup();
        while (root.getParent() != null)
        {
           root = root.getParent();
        }
        
        // I'm not sure why what gets reported is off by +1,
        // but I'm adjusting so that it is consistent with the display
        int activeThreads = root.activeCount()-1;
        // I'm not sure why what gets reported is off by -1
        // but I'm adjusting so that it is consistent with the display
        int activeGroups = root.activeGroupCount()+1;
        
        String rc=
        "<b>Total Threads:</b> "+activeThreads+"<br>"+
        "<b>Total Thread Groups:</b> "+activeGroups+"<br>"+
        getThreadGroupInfo(root) ;
        return rc;
     }
  
     /** Display the java.lang.Package info for the pkgName  */
     public String displayPackageInfo(String pkgName)
     {
        Package pkg = Package.getPackage(pkgName);
        if( pkg == null )
           return "<h2>Package:"+pkgName+" Not Found!</h2>";
  
        StringBuffer info = new StringBuffer("<h2>Package: "+pkgName+"</h2>");
        displayPackageInfo(pkg, info);
        return info.toString();
     }
     /** Display the ClassLoader, ProtectionDomain and Package information for
      the specified class.
      @return a simple html report of this information
      */
     public String displayInfoForClass(String className)
     {
        ServiceLibraries libraries = ServiceLibraries.getLibraries();
        Class clazz = libraries.findClass(className);
        if( clazz == null )
           return "<h2>Class:"+className+" Not Found!</h2>";
        Package pkg = clazz.getPackage();
        if( pkg == null )
           return "<h2>Class:"+className+" has no Package info</h2>";
  
        StringBuffer info = new StringBuffer("<h1>Class: "+pkg.getName()+"</h1>");
        ClassLoader cl = clazz.getClassLoader();
        info.append("<h2>ClassLoader: "+cl+"</h2>\n");
        info.append("<h3>ProtectionDomain</h3>\n");
        info.append("<pre>\n"+clazz.getProtectionDomain()+"</pre>\n");
        info.append("<h2>Package: "+pkg.getName()+"</h2>");
        displayPackageInfo(pkg, info);
        return info.toString();
     }
  
     /** This does not work as expected because the thread context class loader
      *is not used to determine which class loader the package list is obtained
      *from.
      */
     public String displayAllPackageInfo()
     {
        ClassLoader entryCL = Thread.currentThread().getContextClassLoader();
        ServiceLibraries libraries = ServiceLibraries.getLibraries();
        ClassLoader[] classLoaders = libraries.getClassLoaders();
        StringBuffer info = new StringBuffer();
        for(int c = 0; c < classLoaders.length; c ++)
        {
           ClassLoader cl = classLoaders[c];
           Thread.currentThread().setContextClassLoader(cl);
           try
           {
              info.append("<h1>ClassLoader: "+cl+"</h1>\n");
              Package[] pkgs = Package.getPackages();
              for(int p = 0; p < pkgs.length; p ++)
              {
                 Package pkg = pkgs[p];
                 info.append("<h2>Package: "+pkg.getName()+"</h2>\n");
                 displayPackageInfo(pkg, info);
              }
           }
           catch(Throwable e)
           {
           }
        }
        Thread.currentThread().setContextClassLoader(entryCL);
        return info.toString();
     }
     private void displayPackageInfo(Package pkg, StringBuffer info)
     {
        info.append("<pre>\n");
        info.append("SpecificationTitle: "+pkg.getSpecificationTitle());
        info.append("\nSpecificationVersion: "+pkg.getSpecificationVersion());
        info.append("\nSpecificationVendor: "+pkg.getSpecificationVendor());
        info.append("\nImplementationTitle: "+pkg.getImplementationTitle());
        info.append("\nImplementationVersion: "+pkg.getImplementationVersion());
        info.append("\nImplementationVendor: "+pkg.getImplementationVendor());
        info.append("\nisSealed: "+pkg.isSealed());
        info.append("</pre>\n");
     }
  
     /** Return a Map of System.getProperties() with a toString implementation
      *that provides an html table of the key/value pairs
      */
     public Map showProperties()
     {
        return new HashMap(System.getProperties())
        {
           public String toString()
           {
              StringBuffer buff = new StringBuffer();
              buff.append("<table>");
              Iterator iter = keySet().iterator();
              while (iter.hasNext())
              {
                 String key = (String)iter.next();
                 buff.append("<tr><td align=\"left\">")
                 .append(key)
                 .append("</td><td align=\"left\">")
                 .append(get(key))
                 .append("</td></tr>\n\r");
              }
              buff.append("</table>");
              
              return buff.toString();
           }
        };
     }
  
     private String getThreadGroupInfo(ThreadGroup group)
     {
        StringBuffer rc = new StringBuffer();
        
        rc.append("<BR><B>");
        rc.append("Thread Group: " + group.getName());
        rc.append("</B> : ");
        rc.append("max priority:" + group.getMaxPriority() +
        ", demon:" + group.isDaemon());
        
        rc.append("<blockquote>");
        Thread threads[]= new Thread[group.activeCount()];
        group.enumerate(threads, false);
        for (int i= 0; i < threads.length && threads[i] != null; i++)
        {
           rc.append("<B>");
           rc.append("Thread: " + threads[i].getName());
           rc.append("</B> : ");
           rc.append("priority:" + threads[i].getPriority() +
           ", demon:" + threads[i].isDaemon());
           rc.append("<BR>");
        }
        
        ThreadGroup groups[]= new ThreadGroup[group.activeGroupCount()];
        group.enumerate(groups, false);
        for (int i= 0; i < groups.length && groups[i] != null; i++)
        {
           rc.append(getThreadGroupInfo(groups[i]));
        }
        rc.append("</blockquote>");
        
        return rc.toString();
     }
  
  }
  
  
  
  1.1                  
jboss-system/src/main/org/jboss/system/server/ServerInfoMBean.java
  
  Index: ServerInfoMBean.java
  ===================================================================
  /***************************************
   *                                     *
   *  JBoss: The OpenSource J2EE WebOS   *
   *                                     *
   *  Distributable under LGPL license.  *
   *  See terms of license at gnu.org.   *
   *                                     *
   ***************************************/
  
  package org.jboss.system.server;
  
  import java.util.Map;
  
  import javax.management.ObjectName;
  
  import org.jboss.util.jmx.ObjectNameFactory;
  
  /**
   * The management interface for the Info bean.
   *      
   * @author <a href="mailto:[EMAIL PROTECTED]";>Rickard �berg</a>
   * @author <a href="mailto:[EMAIL PROTECTED]";>Hiram Chirino</a>
   * @author <a href="mailto:[EMAIL PROTECTED]";>Jason Dillon</a>
   * @author <a href="mailto:[EMAIL PROTECTED]";>Marc Fleury</a>
   * @author <a href="mailto:[EMAIL PROTECTED]";>Scott Stark</a>
   * @version $Revision: 1.1 $
   */
  public interface ServerInfoMBean
  {
     /** The default JMX object name for this MBean. */
     ObjectName OBJECT_NAME =
        ObjectNameFactory.create("jboss.system:type=ServerInfo");
  
     /**
      * InetAddress.getLocalHost().getHostName();
      */
     String getHostName();
     
     /**
      * Returns InetAddress.getLocalHost().getHostAddress();
      */
     String getHostAddress();
     
     /**
      * Return the total memory and free memory from Runtime
      */
     String listMemoryUsage();
     
     /**
      * Return a listing of the active threads and thread groups.
      */
     String listThreadDump();
     
     /**
      * Display the java.lang.Package info for the pkgName
      */
     String displayPackageInfo(String pkgName);
  
     /** 
      * Display the ClassLoader, ProtectionDomain and Package information for
      * the specified class.
      *
      * @return a simple html report of this information
      */
     String displayInfoForClass(String className);
  
     /**
      * Return a Map of System.getProperties() with a toString implementation
      * that provides an html table of the key/value pairs
      */
     Map showProperties();   
  }
  
  
  

_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to