All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mortbay.start.Main Maven / Gradle / Ivy

The newest version!
// ========================================================================
// Copyright (c) 2003 Mort Bay Consulting (Australia) Pty. Ltd.
// $Id: Main.java 6177 2007-02-19 10:11:27Z aaime $
// ========================================================================
package org.mortbay.start;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.Policy;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.StringTokenizer;


/*-------------------------------------------*/
/** Main start class.
 * This class is intended to be the main class listed in the MANIFEST.MF  of
 * the start.jar archive. It allows an application to be started with the
 * command "java -jar start.jar".
 *
 * The behaviour of Main is controlled by the "org/mortbay/start/start.config"
 * file obtained as a resource or file. This can be overridden with the START
 * system property.
 *
 * The format of each line in this file is:
 *  SUBJECT [ [!] CONDITION [AND|OR] ]*
 * 
* where SUBJECT:
 *   ends with ".class" is the Main class to run.
 *   ends with ".xml" is a configuration file for the command line
 *   ends with "/" is a directory from which add all jar and zip files from.
 *   ends with "/*" is a directory from which add all unconsidered jar and zip files from.
 *   Containing = are used to assign system properties.
 *   all other subjects are treated as files to be added to the classpath.
 * 
* Subjects may include system properties with $(propertyname) syntax. * File subjects starting with "/" are considered absolute, all others are relative to * the home directory. *

* CONDITION is one of:

 *   always
 *   never
 *   available package.class
 *   java OPERATOR n.n
 *   nargs OPERATOR n
 *   OPERATOR := one of "<",">","<=",">=","==","!="
 * 
* CONTITIONS can be combined with AND OR or !, with AND being the assume * operator for a list of CONDITIONS. * Classpath operations are evaluated on the fly, so once a class or jar is * added to the classpath, subsequent available conditions will see that class. * * The system parameter CLASSPATH, if set is given to the start classloader before * any paths from the configuration file. * * Programs started with start.jar may be stopped with the stop.jar, which connects * via a local port to stop the server. The default port can be set with the * STOP.PORT system property (a port of < 0 disables the stop mechanism). If the STOP.KEY * system property is set, then a random key is generated and written to stdout. This key * must be passed to the stop.jar. * * @author Jan Hlavaty ([email protected]) * @author Greg Wilkins * @version $Revision: 1.1 $ */ public class Main { static boolean _debug = System.getProperty("DEBUG", null) != null; private String _classname = null; private Classpath _classpath = new Classpath(); private String _config = System.getProperty("START", "org/mortbay/start/start.config"); private ArrayList _xml = new ArrayList(); public static void main(String[] args) { try { new Main().start(args); } catch (Exception e) { e.printStackTrace(); } } static File getDirectory(String name) { try { if (name != null) { File dir = new File(name).getCanonicalFile(); if (dir.isDirectory()) { return dir; } } } catch (IOException e) { } return null; } boolean isAvailable(String classname) { try { Class.forName(classname); return true; } catch (ClassNotFoundException e) { } ClassLoader loader = _classpath.getClassLoader(); try { loader.loadClass(classname); return true; } catch (ClassNotFoundException e) { } return false; } public static void invokeMain(ClassLoader classloader, String classname, String[] args) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, ClassNotFoundException { Class invoked_class = null; invoked_class = classloader.loadClass(classname); Class[] method_param_types = new Class[1]; method_param_types[0] = args.getClass(); Method main = null; main = invoked_class.getDeclaredMethod("main", method_param_types); Object[] method_params = new Object[1]; method_params[0] = args; main.invoke(null, method_params); } /* ------------------------------------------------------------ */ String expand(String s) { int i1 = 0; int i2 = 0; while (s != null) { i1 = s.indexOf("$(", i2); if (i1 < 0) { break; } i2 = s.indexOf(")", i1 + 2); if (i2 < 0) { break; } String property = System.getProperty(s.substring(i1 + 2, i2), ""); s = s.substring(0, i1) + property + s.substring(i2 + 1); } return s; } /* ------------------------------------------------------------ */ void configure(InputStream config, String[] args) throws Exception { BufferedReader cfg = new BufferedReader(new InputStreamReader(config, "ISO-8859-1")); Version java_version = new Version(System.getProperty("java.version")); Version ver = new Version(); // JAR's already processed java.util.Hashtable done = new Hashtable(); // Initial classpath String classpath = System.getProperty("CLASSPATH"); if (classpath != null) { StringTokenizer tok = new StringTokenizer(classpath, File.pathSeparator); while (tok.hasMoreTokens()) _classpath.addComponent(tok.nextToken()); } // Handle line by line String line = null; while (true) { line = cfg.readLine(); if (line == null) { break; } if ((line.length() == 0) || line.startsWith("#")) { continue; } try { StringTokenizer st = new StringTokenizer(line); String subject = st.nextToken(); boolean expression = true; boolean not = false; String condition = null; // Evaluate all conditions while (st.hasMoreTokens()) { condition = st.nextToken(); if (condition.equalsIgnoreCase("!")) { not = true; continue; } if (condition.equalsIgnoreCase("OR")) { if (expression) { break; } expression = true; continue; } if (condition.equalsIgnoreCase("AND")) { if (!expression) { break; } continue; } boolean eval = true; if (condition.equals("true") || condition.equals("always")) { eval = true; } else if (condition.equals("false") || condition.equals("never")) { eval = false; } else if (condition.equals("available")) { String class_to_check = st.nextToken(); eval = isAvailable(class_to_check); } else if (condition.equals("exists")) { try { eval = false; File file = new File(expand(st.nextToken())); eval = file.exists(); } catch (Exception e) { if (_debug) { e.printStackTrace(); } } } else if (condition.equals("java")) { String operator = st.nextToken(); String version = st.nextToken(); ver.parse(version); eval = (operator.equals("<") && (java_version.compare(ver) < 0)) || (operator.equals(">") && (java_version.compare(ver) > 0)) || (operator.equals("<=") && (java_version.compare(ver) <= 0)) || (operator.equals("=<") && (java_version.compare(ver) <= 0)) || (operator.equals("=>") && (java_version.compare(ver) >= 0)) || (operator.equals(">=") && (java_version.compare(ver) >= 0)) || (operator.equals("==") && (java_version.compare(ver) == 0)) || (operator.equals("!=") && (java_version.compare(ver) != 0)); } else if (condition.equals("nargs")) { String operator = st.nextToken(); int number = Integer.parseInt(st.nextToken()); eval = (operator.equals("<") && (args.length < number)) || (operator.equals(">") && (args.length > number)) || (operator.equals("<=") && (args.length <= number)) || (operator.equals("=<") && (args.length <= number)) || (operator.equals("=>") && (args.length >= number)) || (operator.equals(">=") && (args.length >= number)) || (operator.equals("==") && (args.length == number)) || (operator.equals("!=") && (args.length != number)); } else { System.err.println("ERROR: Unknown condition: " + condition); eval = false; } expression &= (not ? (!eval) : eval); not = false; } String file = expand(subject).replace('/', File.separatorChar); if (_debug) { System.err.println((expression ? "T " : "F ") + line); } if (!expression) { done.put(file, file); continue; } // Handle the subject if (subject.indexOf("=") > 0) { int i = file.indexOf("="); String property = file.substring(0, i); String value = file.substring(i + 1); if (_debug) { System.err.println(" " + property + "=" + value); } System.setProperty(property, value); } else if (subject.endsWith("/*")) { // directory of JAR files File extdir = new File(file.substring(0, file.length() - 1)); File[] jars = extdir.listFiles(new FilenameFilter() { public boolean accept(File dir, String name) { String namelc = name .toLowerCase(); return namelc.endsWith(".jar") || name.endsWith(".zip"); } }); for (int i = 0; (jars != null) && (i < jars.length); i++) { String jar = jars[i].getCanonicalPath(); if (!done.containsKey(jar)) { done.put(jar, jar); boolean added = _classpath.addComponent(jar); if (_debug) { System.err.println((added ? " CLASSPATH+=" : " !") + jar); } } } } else if (subject.endsWith("/")) { // class directory File cd = new File(file); String d = cd.getCanonicalPath(); if (!done.containsKey(d)) { done.put(d, d); boolean added = _classpath.addComponent(d); if (_debug) { System.err.println((added ? " CLASSPATH+=" : " !") + d); } } } else if (subject.toLowerCase().endsWith(".xml")) { // Config file File f = new File(file); if (f.exists()) { _xml.add(f.getCanonicalPath()); } if (_debug) { System.err.println(" ARGS+=" + f); } } else if (subject.toLowerCase().endsWith(".class")) { // Class String cn = expand(subject.substring(0, subject.length() - 6)); if ((cn != null) && (cn.length() > 0)) { if (_debug) { System.err.println(" CLASS=" + cn); } _classname = cn; } } else { // single JAR file File f = new File(file); String d = f.getCanonicalPath(); if (!done.containsKey(d)) { done.put(d, d); boolean added = _classpath.addComponent(d); if (!added) { added = _classpath.addClasspath(expand(subject)); if (_debug) { System.err.println((added ? " CLASSPATH+=" : " !") + d); } } else if (_debug) { System.err.println((added ? " CLASSPATH+=" : " !") + d); } } } } catch (Exception e) { System.err.println("on line: '" + line + "'"); e.printStackTrace(); } } } /* ------------------------------------------------------------ */ public void start(String[] args) { // set up classpath: try { Monitor.monitor(); InputStream cpcfg = getClass().getClassLoader().getResourceAsStream(_config); if (_debug) { System.err.println("config=" + _config); } if (cpcfg == null) { cpcfg = new FileInputStream(_config); } configure(cpcfg, args); cpcfg.close(); File file = new File(System.getProperty("jetty.home")); String canonical = file.getCanonicalPath(); System.setProperty("jetty.home", canonical); } catch (Exception e) { e.printStackTrace(); System.exit(1); } // okay, classpath complete. System.setProperty("java.class.path", _classpath.toString()); ClassLoader cl = _classpath.getClassLoader(); if (_debug) { System.err.println("java.class.path=" + System.getProperty("java.class.path")); } if (_debug) { System.err.println("jetty.home=" + System.getProperty("jetty.home")); } if (_debug) { System.err.println("java.io.tmpdir=" + System.getProperty("java.io.tmpdir")); } if (_debug) { System.err.println("java.class.path=" + _classpath); } if (_debug) { System.err.println("classloader=" + cl); } if (_debug) { System.err.println("classloader.parent=" + cl.getParent()); } // Invoke main(args) using new classloader. Thread.currentThread().setContextClassLoader(cl); // re-eval the policy now that env is set try { Policy policy = Policy.getPolicy(); if (policy != null) { policy.refresh(); } } catch (Exception e) { e.printStackTrace(); } try { if (_xml.size() > 0) { for (int i = 0; i < args.length; i++) _xml.add(args[i]); args = (String[]) _xml.toArray(args); } //check for override of start class String serverOverride = System.getProperty("jetty.server"); if (_debug) { System.err.println("server.override=" + serverOverride); } if (serverOverride != null) { _classname = serverOverride; } invokeMain(cl, _classname, args); } catch (Exception e) { e.printStackTrace(); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy