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