User: chirino
Date: 02/02/23 11:33:02
Modified: src/main/org/jboss Boot.java
Log:
Enhancments:
- Boot can now be used applications to boot other applications.
- Added a few debug messages
- ContextClassLoader is now getting set for the application.
- Added a -help option
Revision Changes Path
1.2 +194 -89 jboss/src/main/org/jboss/Boot.java
Index: Boot.java
===================================================================
RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/Boot.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Boot.java 21 Feb 2002 23:17:00 -0000 1.1
+++ Boot.java 23 Feb 2002 19:33:02 -0000 1.2
@@ -29,11 +29,26 @@
* start the test.App2TEST application.
* Important Note: Notice that there are spaces before and after the ","!!!
*
- * TODO: Add debug print statments to help users figure out when they are
improperly using this class.
- * TODO: Bring in some of the features that are in the org.jboss.main like the
jboss.boot.loader.name property
+ * You can now boot other applications via ths Boot class from withing one of the
applications
+ * that was booted by the Boot.
*
- * @author <a href="mailto:[EMAIL PROTECTED]">Hiram Chirino</a>
+ * Example usage:
+ * <code>
+ * Boot b = Boot.getInstance();
+ * Boot.ApplicationBoot ab = b.createApplicationBoot();
+ * ab.applicationClass = "org.jboss.Main"
+ * ab.classpath.add(new URL("file:run.jar"));
+ * ab.args.add("default");
+ *
+ * // this would start the application in a new thread.
+ * b.startApplication( ab );
+ *
+ * // Would boot the appp in the current thread.
+ * ab.boot();
*
+ * </code>
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]">Hiram Chirino</a>
*/
public class Boot
{
@@ -41,35 +56,49 @@
/**
* Indicates whether this instance is running in debug mode.
*/
- protected boolean debug = false;
-
+ protected boolean verbose = false;
+
/**
* For each booted application, we will store a ApplicationBoot object in this
linked list.
*/
- protected LinkedList applicationBoots;
-
- // constants
- private static final String DEBUG = "-debug";
- private static final String BOOT_APP_SEPERATOR =
System.getProperty("org.jboss.Boot.APP_SEPERATOR", ",");
- private static final String CP = "-cp";
+ protected LinkedList applicationBoots = new LinkedList();
+ static Boot instance;
+ ThreadGroup bootThreadGroup;
+
+ /**
+ * If boot is accessed via an API, force the use of the getInstance() method.
+ */
+ protected Boot () {
+ instance = this;
+ bootThreadGroup = Thread.currentThread().getThreadGroup();
+ }
+
+ public static Boot getInstance() {
+ if( instance == null )
+ instance = new Boot();
+ return instance;
+ }
/**
- * Data that is extracted for each mbus app that is specified on the command line
+ * Represents an application that can be booted.
*/
- class ApplicationBoot implements Runnable
+ public class ApplicationBoot implements Runnable
{
-
- LinkedList classpath = new LinkedList();
- String applicationClass;
- LinkedList passThruArgs = new LinkedList();
- URLClassLoader classloader;
- boolean isRunning;
-
- /**
- * This is what actually loads the application classes and
- * invokes the main method. We send any unhandled exceptions to
- * System.err
- */
+ /** LinkedList of URL that will be used to load the application's
classes and resources */
+ public LinkedList classpath = new LinkedList();
+ /** The applications class that will be executed. */
+ public String applicationClass;
+ /** The aruments that will appsed to the application. */
+ public LinkedList args = new LinkedList();
+
+ protected URLClassLoader classloader;
+ protected Thread bootThread;
+
+ /**
+ * This is what actually loads the application classes and
+ * invokes the main method. We send any unhandled exceptions to
+ * System.err
+ */
public void run()
{
try
@@ -83,28 +112,36 @@
}
}
- /**
- * This is what actually loads the application classes and
- * invokes the main method.
- */
+ /**
+ * This is what actually loads the application classes and
+ * invokes the main method.
+ */
public void boot()
throws ClassNotFoundException, NoSuchMethodException,
IllegalAccessException, InvocationTargetException
{
+ verbose("Booting: "+applicationClass);
+ verbose("Classpath: "+classpath);
+ verbose("Arguments: "+args);
+
+ bootThread = Thread.currentThread();
URL urls[] = new URL[classpath.size()];
urls = (URL[]) classpath.toArray(urls);
- String args[] = new String[passThruArgs.size()];
- args = (String[]) passThruArgs.toArray(args);
+ String passThruArgs[] = new String[args.size()];
+ passThruArgs = (String[]) args.toArray(passThruArgs);
- classloader = new URLClassLoader(urls,
Thread.currentThread().getContextClassLoader());
- Class appClass = classloader.loadClass(applicationClass);
- Method mainMethod = appClass.getMethod("main", new Class[] {
String[].class });
+ // Save the current loader so we can restore it.
+ ClassLoader oldCL =
Thread.currentThread().getContextClassLoader();
+
+ try {
+
+ classloader = new URLClassLoader(urls); // The parent is the system CL
+ Thread.currentThread().setContextClassLoader(classloader);
+
+ Class appClass = classloader.loadClass(applicationClass);
+ Method mainMethod = appClass.getMethod("main", new Class[] {
String[].class });
- try
-
- {
- isRunning = true;
- mainMethod.invoke(null, new Object[] { args });
+ mainMethod.invoke(null, new Object[] { passThruArgs });
}
catch (InvocationTargetException e)
{
@@ -115,61 +152,115 @@
}
finally
{
- isRunning = false;
+ // Restore the previous classloader ( in case we were called directly
+ // an not via a Thread.start() )
+ Thread.currentThread().setContextClassLoader(oldCL);
}
}
}
+
+ /**
+ * This can be used to boot another application
+ * From within another one.
+ *
+ * @returns ApplicationBoot data structure that must be configured before the
application can be booted.
+ */
+ public ApplicationBoot createApplicationBoot() {
+ return new ApplicationBoot();
+ }
/**
- * Main entry point when called from the command line
- * @param args the command line arguments
+ * Boots the application in a new threadgroup and thread.
+ *
+ * @param bootData the application to boot.
+ * @exception thrown if a problem occurs during launching
*/
- public static void main(String[] args)
+ synchronized public void startApplication(ApplicationBoot bootData) throws
Exception
{
- try
- {
- new Boot().run(args);
- }
- catch (Throwable e)
+ if( bootData == null )
+ throw new NullPointerException("Invalid argument: bootData argument
was null");
+
+ applicationBoots.add(bootData);
+ ThreadGroup threads = new ThreadGroup(bootThreadGroup,
bootData.applicationClass);
+ new Thread(threads, bootData, "main").start();
+ }
+
+ synchronized public ApplicationBoot[] getStartedApplications() {
+ ApplicationBoot rc[] = new ApplicationBoot[applicationBoots.size()];
+ return (ApplicationBoot[])applicationBoots.toArray(rc);
+ }
+
+ /** logs verbose message to the console */
+ protected void verbose(String msg) {
+ if( verbose )
+ System.out.println("[Boot] "+msg);
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ // THE FOLLOWING SET OF FUNCTIONS ARE RELATED TO PROCESSING COMMAND LINE
+ // ARGUMENTS.
+ //
+ //////////////////////////////////////////////////////////////////////
+ protected static final String HELP = "-help";
+ protected static final String VERBOSE = "-verbose";
+ protected static final String BOOT_APP_SEPERATOR =
System.getProperty("org.jboss.Boot.APP_SEPERATOR", ",");
+ protected static final String CP = "-cp";
+
+ protected static class InvalidCommandLineException extends Exception {
+ /**
+ * Constructor for InvalidCommandLineException.
+ * @param s
+ */
+ public InvalidCommandLineException(String s)
{
- System.err.println("Exception launching the application(s):");
- e.printStackTrace(System.err);
+ super(s);
}
- }
-
-
+ }
+
/**
- * @param args the arguments to the Boot class, see class description
- * @exception thrown if a problem occurs during launching
+ * Main entry point when called from the command line
+ * @param args the command line arguments
*/
- public void run(String[] args) throws Exception
+ public static void main(String[] args)
{
+ Boot boot = Boot.getInstance();
+
// Put the args in a linked list since it easier to work with.
LinkedList llargs = new LinkedList();
for (int i = 0; i < args.length; i++)
- {
llargs.add(args[i]);
- }
- applicationBoots = processCommandLine(llargs);
- Iterator i = applicationBoots.iterator();
- while (i.hasNext())
- {
- ApplicationBoot bootData = (ApplicationBoot) i.next();
- bootApplication(bootData);
- }
+ try {
+
+ LinkedList ab = boot.processCommandLine(llargs);
+ Iterator i = ab.iterator();
+ while (i.hasNext())
+ {
+ ApplicationBoot bootData = (ApplicationBoot) i.next();
+ boot.startApplication(bootData);
+ }
+
+ } catch ( InvalidCommandLineException e ) {
+ System.err.println("Invalid Usage: "+e.getMessage());
+ System.err.println();
+ showUsage();
+ System.exit(1);
+ } catch ( Throwable e ) {
+ System.err.println("Failure occured while executing application: ");
+ e.printStackTrace(System.err);
+ System.exit(1);
+ }
}
-
+
/**
- * Boots the application in a new threadgroup and thread.
- *
- * @param bootData the application to boot.
- * @exception thrown if a problem occurs during launching
+ * This method is here so that if JBoss is running under
+ * Alexandria (An NT Service Installer), Alexandria can shutdown
+ * the system down correctly.
*/
- public void bootApplication(ApplicationBoot bootData) throws Exception
+ public static void systemExit(String argv[])
{
- ThreadGroup threads = new ThreadGroup(bootData.applicationClass);
- new Thread(threads, bootData, "main").start();
+ System.exit(0);
}
/**
@@ -192,7 +283,7 @@
if (rc.size() == 0)
{
- throw new Exception("Invlid usage: An application class name must be
provided.");
+ throw new InvalidCommandLineException("An application class name must be
provided.");
}
return rc;
@@ -209,12 +300,17 @@
while (i.hasNext())
{
String arg = (String) i.next();
- if (arg.equalsIgnoreCase(DEBUG))
+ if (arg.equalsIgnoreCase(VERBOSE))
{
- debug = true;
+ verbose = true;
i.remove();
continue;
}
+ if (arg.equalsIgnoreCase(HELP))
+ {
+ showUsage();
+ System.exit(0);
+ }
// Didn't recognize it a boot option, then we must have started the
application
// boot options.
@@ -222,6 +318,24 @@
}
}
+ protected static void showUsage()
+ {
+ String programName = System.getProperty("org.jboss.Boot.proces-name", "boot");
+
+ System.out.println("usage: " + programName + " [boot-options] [app-options]
class [args..]");
+ System.out.println(" to execute a class");
+ System.out.println(" or " + programName + " [boot-options] [app-options]
class-1 [args..] , ... , [app-options] class-n [args..]");
+ System.out.println(" to execute multiple classes");
+ System.out.println();
+ System.out.println("boot-options:");
+ System.out.println(" -help show this help message");
+ System.out.println(" -verbose display detail messages regarding the
boot process.");
+ System.out.println("app-options:");
+ System.out.println(" -cp <directories and zip/jar urls separated by ,> ");
+ System.out.println(" set search path for application classes
and resources");
+ System.out.println();
+ }
+
/**
* Processes the command line argumenst for the next application on the command
line.
*
@@ -242,7 +356,7 @@
if (arg.equalsIgnoreCase(CP))
{
if (!i.hasNext())
- throw new Exception("Invalid option: classpath missing after the
" + CP + " option.");
+ throw new InvalidCommandLineException("Invalid option: classpath
missing after the " + CP + " option.");
String cp = (String) i.next();
i.remove();
@@ -259,7 +373,7 @@
}
catch (MalformedURLException e)
{
- throw new Exception("Application classpath value was invalid:
" + e.getMessage());
+ throw new InvalidCommandLineException("Application classpath
value was invalid: " + e.getMessage());
}
}
continue;
@@ -274,7 +388,7 @@
{
break;
}
- rc.passThruArgs.add(arg);
+ rc.args.add(arg);
}
}
@@ -285,13 +399,4 @@
return rc;
}
- /**
- * This method is here so that if JBoss is running under
- * Alexandria (An NT Service Installer), Alexandria can shutdown
- * the system down correctly.
- */
- public static void systemExit(String argv[])
- {
- System.exit(0);
- }
-}
+}
\ No newline at end of file
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development