/* * This software is distributed under the terms of the FSF * Gnu Lesser General Public License (see lgpl.txt). * * This program is distributed WITHOUT ANY WARRANTY. See the * GNU General Public License for more details. */ package com.scooterframework.tools.webserver; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import com.scooterframework.tools.common.ToolsUtil; /** * StartServer class starts web server. This class exposes the following * system properties if they have not been defined. * <pre> * scooter.home -> path to scooter home * app.name -> application name * app.logs -> location of application logs * app.path -> path to a specific web app * jetty.home -> path to jetty server * jetty.logs -> location of jetty logs * jetty.port -> port number of jetty server * jdk.home -> path to JDK (only if tools.jar is detected) * START -> configuration file of jetty server * webapps.name -> name of webapps directory (default is webapps) * webapps.path -> path to webapps directory * </pre> * * Original Jetty command line options are also supported: * <tt>-DDEBUG, --help, --version, --stop</tt> * * <p> * Examples: * <pre> Usage: java -jar tools/server.jar app_name [port, [config ...]] Examples: This page: java -jar tools/server.jar -help Run Jetty Server with default jetty.xml in tools/servers/jetty/etc and port 8080: java -jar tools/server.jar blog Run Jetty Server with default jetty.xml in tools/servers/jetty/etc but on port 8090: java -jar tools/server.jar blog 8090 Run Jetty Server with the blog sample app on port 8091: java -jar tools/server.jar examples/blog 8091 Run Jetty Server with the blog sample app installed in user home: java -jar tools/server.jar /home/john/blog Run Jetty Server as JettyPlus (JNDI, JAAS etc.) with config files in tools/servers/jetty/etc: java -jar tools/server.jar blog etc/jetty-plus.xml etc/jetty.xml * </pre> * </p> * * @author (Fei) John Chen */ public class StartServer { public static void main(String[] args) { if ((args.length > 0 && args[0].equalsIgnoreCase("-help")) || args.length < 1) { usage(); return; } try { doTheWork(args); } catch(Throwable ex) { ex.printStackTrace(); log("ERROR ERROR ERROR: " + ex.getMessage()); } } private static void doTheWork(String[] args) throws Throwable { String scooterHome = (new File("")).getCanonicalPath(); scooterHome = ToolsUtil.setSystemProperty("scooter.home", scooterHome); String jettyHome = scooterHome + File.separator + "tools" + File.separator + "servers" + File.separator + "jetty"; jettyHome = ToolsUtil.setSystemProperty("jetty.home", jettyHome); String START = jettyHome + File.separator + "start.config"; START = ToolsUtil.setSystemProperty("START", START); if (args[0].startsWith("--")) { startUp(args); return; } String defaultWebappsName = ToolsUtil.setSystemProperty("webapps.name", "webapps"); String appName = ""; String webappsPath = ""; String webappPath = ""; String firstArg = args[0]; if (ToolsUtil.containsPath(firstArg)) { String[] ss = ToolsUtil.getPathAndName(firstArg); webappsPath = ss[0]; webappPath = ss[1]; appName = ss[2]; } else { appName = firstArg; webappsPath = scooterHome + File.separator + defaultWebappsName; webappPath = webappsPath + File.separator + appName; } System.setProperty("app.name", appName); webappsPath = ToolsUtil.setSystemProperty("webapps.path", webappsPath); webappPath = ToolsUtil.setSystemProperty("app.path", webappPath); ToolsUtil.validatePathExistence(webappPath); boolean foundPort = false; List<String> argItems = new ArrayList<String>(); String port = "8080"; String jettyXML = "etc/jetty.xml"; if (args.length > 1) { foundPort = isNumber(args[1]); if (foundPort) { port = args[1]; System.setProperty("jetty.port", port); if (args.length == 2) { argItems.add(jettyXML); } else { argItems.addAll(getXMLs(args, 2)); } } else { argItems.addAll(getXMLs(args, 1)); } } else if (args.length == 1) { argItems.add(jettyXML); } String jettyLogs = jettyHome + File.separator + "logs"; jettyLogs = ToolsUtil.setSystemProperty("jetty.logs", jettyLogs); String appLogs = webappPath + File.separator + "WEB-INF" + File.separator + "log"; appLogs = ToolsUtil.setSystemProperty("app.logs", appLogs); validateXMLsExistence(jettyHome, argItems); String jettyXMLsAsString = getXMLsAsString(jettyHome, argItems); // String jdkHome = getJDKHome(); // boolean foundToolsJar = existsToolsJar(jdkHome); // if (foundToolsJar) { // jdkHome = ToolsUtil.setSystemProperty("jdk.home", jdkHome); // } // else { // throw new IllegalArgumentException("You must run this program from a JDK."); // } String hr = "========================================="; log(hr); log(""); if (foundPort) { log("Starting Jetty Web Server on port " + port); } else { log("Starting Jetty Web Server on default port " + port); } //some basic info log(""); log("scooter.home: " + scooterHome); log(" app.name: " + appName); log(" app.logs: " + appLogs); log(" app.path: " + webappPath); log(" app.port: " + port); log(" jetty.home: " + jettyHome); log(" jetty.logs: " + jettyLogs); log(" jetty.init: " + START); log(" jetty.xmls: " + jettyXMLsAsString); log(""); // if (!foundToolsJar) { // log("No tools.jar found in \"" + jdkHome + File.separator + "lib\". "); // log("tools.jar is required if using DEVELOPMENT mode."); // log(""); // } log("Use Ctrl-C to shutdown server"); log(""); log(hr); startUp(jettyHome, argItems); } private static boolean isNumber(String s) { boolean status = true; try { Integer.parseInt(s); } catch(Exception ex) { status = false; } return status; } private static List<String> getXMLs(String[] ary, int start) { List<String> list = new ArrayList<String>(); for (int i = start; i < ary.length; i++) { list.add(ary[i]); } return list; } private static void validateXMLsExistence(String jettyHome, List<String> names) { Iterator<String> it = names.iterator(); while(it.hasNext()) { String name = it.next(); if (!name.endsWith(".xml")) continue; String jettyXMLPath = jettyHome + File.separator + name; File jx = new File(jettyXMLPath); if (!jx.exists()) { log(""); log("ERROR ERROR ERROR: The required jetty configuration file [" + jettyXMLPath + "] does not exist."); log(""); log("System exits now."); System.exit(-1); } } } private static String getXMLsAsString(String jettyHome, List<String> jettyXMLs) { StringBuilder sb = new StringBuilder(); Iterator<String> it = jettyXMLs.iterator(); while(it.hasNext()) { sb.append(jettyHome).append(File.separator); sb.append(it.next()).append(", "); } String s = sb.toString(); return (s.endsWith(", "))?s.substring(0, s.length()-2):s; } @SuppressWarnings("unused") private static String getJDKHome() { String s = System.getProperty("java.home"); return s.substring(0, s.length()-4); } @SuppressWarnings("unused") private static boolean existsToolsJar(String jdkHome) { boolean exist = false; File f = new File(jdkHome + File.separator + "lib" + File.separator + "tools.jar"); if (f.exists()) { exist = true; } return exist; } public static void startUp(String[] args) throws Exception { ClassLoader cl = Thread.currentThread().getContextClassLoader(); String jettyMainClassName = "org.mortbay.start.Main"; invokeMain(cl, jettyMainClassName, args); } public static void startUp(String jettyHome, List<String> argItems) throws Exception { ClassLoader cl = Thread.currentThread().getContextClassLoader(); String jettyMainClassName = "org.mortbay.start.Main"; String[] args=(String[])argItems.toArray(new String[argItems.size()]); for (int i = 0; i < argItems.size(); i++) { String s = args[i]; if (s.endsWith(".xml") && s.startsWith("etc")) { args[i] = jettyHome + File.separator + s; } } invokeMain(cl, jettyMainClassName, args); } private static void invokeMain(ClassLoader classloader, String classname, String[] args) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, ClassNotFoundException { Class<?> invoked_class = classloader.loadClass(classname); Class<?>[] method_param_types = new Class[1]; method_param_types[0]= args.getClass(); Method main = invoked_class.getDeclaredMethod("main", method_param_types); Object[] method_params = new Object[1]; method_params[0] = args; main.invoke(null, method_params); } private static void log(Object o) { System.out.println("scooTer> " + o); } private static void usage() { log("Summary:"); log(" This is a utility that starts an embedded Jetty Web Server."); log(""); log("Usage:"); log(" java -jar tools/server.jar app_name [port, [config ...]]"); log(""); log("Examples:"); log(" This page:"); log(" java -jar tools/server.jar -help"); log(""); log(" Run Jetty Server with default jetty.xml in tools/servers/jetty/etc and port 8080:"); log(" java -jar tools/server.jar blog"); log(""); log(" Run Jetty Server with default jetty.xml in tools/servers/jetty/etc but on port 8090:"); log(" java -jar tools/server.jar blog 8090"); log(""); log(" Run Jetty Server with the blog sample app on port 8091:"); log(" java -jar tools/server.jar examples/blog 8091"); log(""); log(" Run Jetty Server with the blog sample app installed in user home:"); log(" java -jar tools/server.jar /home/john/blog"); log(""); log(" Run Jetty Server as JettyPlus (JNDI, JAAS etc.) with config files in tools/servers/jetty/etc:"); log(" java -jar tools/server.jar blog etc/jetty-plus.xml etc/jetty.xml"); log(""); } }