From c0076898b0885ce8dc294ed9af77bb091c2fb94f Mon Sep 17 00:00:00 2001 From: hns Date: Mon, 15 Dec 2003 17:08:06 +0000 Subject: [PATCH] Added Helma Command line invoker contributed by Stefan Pollach --- src/helma/main/CommandlineRunner.java | 102 +++++++++++++++ src/helma/main/launcher/Commandline.java | 58 +++++++++ src/helma/main/launcher/Main.java | 156 ++++++++++++++--------- 3 files changed, 259 insertions(+), 57 deletions(-) create mode 100644 src/helma/main/CommandlineRunner.java create mode 100644 src/helma/main/launcher/Commandline.java diff --git a/src/helma/main/CommandlineRunner.java b/src/helma/main/CommandlineRunner.java new file mode 100644 index 00000000..e813a248 --- /dev/null +++ b/src/helma/main/CommandlineRunner.java @@ -0,0 +1,102 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + +package helma.main; + +import helma.framework.core.Application; +import helma.util.SystemProperties; +import java.io.File; +import java.util.*; + +/** + * Helma bootstrap class. Figures out Helma home directory, sets up class path and + * lauchnes main class. This class must be invoked from a jar file in order to work. + * + * @author Stefan Pollach + */ +public class CommandlineRunner { + + /** + * boot method for running a request from the command line. + * This retrieves the Helma home directory, creates the + * classpath, get the request properties, creates the app and + * runs it + *- + * @param args command line arguments + * + * @throws Exception if the Helma home dir or classpath couldn't be built + */ + public static void main(String[] args) throws Exception { + + // parse arguments + String commandStr = null; + for (int i = 0; i < args.length; i++) { + if ((i%2)==0 && !args[i].startsWith("-")) { + commandStr = args[i]; + } + } + + String appName = null; + String function = null; + try { + int pos1 = commandStr.indexOf("."); + appName = commandStr.substring(0, pos1); + function = commandStr.substring(pos1+1); + } catch (Exception str) { + System.out.println("Error parsing command"); + System.out.println(""); + System.out.println("Usage: java helma.main.launcher.Commandline [appname].[function]"); + System.out.println(""); + System.exit(1); + } + + String installDir = System.getProperty("helma.home"); + + String propsPath = new File(installDir, "apps.properties").getAbsolutePath(); + // try to load server properties + SystemProperties props = new SystemProperties(propsPath); + + String appPath = props.getProperty(appName+".appdir"); + String dbPath = props.getProperty(appName+".dbdir"); + + File appHome = appPath == null ? + new File(new File(installDir, "apps"), appName) : + new File(appPath); + File dbHome = dbPath == null ? + new File(new File(installDir, "db"), appName) : + new File(dbPath); + + // set up helma logging + System.setProperty("org.apache.commons.logging.LogFactory", + "helma.util.Logging"); + System.setProperty("helma.logdir", "console"); + + Application app = new Application(appName, appHome, dbHome); + + // init + start the app + app.init(); + app.start(); + + // execute the function + Vector nargs = new Vector(); + Object result = app.executeExternal(function, nargs); + System.out.println("got result " + result); + + // stop the app + app.stop(); + + } +} diff --git a/src/helma/main/launcher/Commandline.java b/src/helma/main/launcher/Commandline.java new file mode 100644 index 00000000..3c118d92 --- /dev/null +++ b/src/helma/main/launcher/Commandline.java @@ -0,0 +1,58 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + +package helma.main.launcher; + +import java.lang.reflect.*; + +/** + * Helma bootstrap class. Figures out Helma home directory, sets up class path and + * lauchnes main class. This class must be invoked from a jar file in order to work. + * + * @author Stefan Pollach + */ +public class Commandline { + + /** + * boot method for running a request from the command line. + * This retrieves the Helma home directory, creates the + * classpath, get the request properties, creates the app and + * runs it + *- + * @param args command line arguments + */ + public static void main(String[] args) { + try { + String installDir = Main.getInstallDir(args); + + FilteredClassLoader loader = Main.createClassLoader(installDir); + + // get the main server class + Class clazz = loader.loadClass("helma.main.CommandlineRunner"); + Class[] cargs = new Class[]{args.getClass()}; + Method main = clazz.getMethod("main", cargs); + Object[] nargs = new Object[]{args}; + + // and invoke the static main(String, String[]) method + main.invoke(null, nargs); + } catch (Exception x) { + // unable to get Helma installation dir from launcher jar + System.err.println("Unable to get Helma installation directory: "); + System.err.println(x.getMessage()); + System.exit(2); + } + } +} diff --git a/src/helma/main/launcher/Main.java b/src/helma/main/launcher/Main.java index 53bec2dc..50e6426e 100644 --- a/src/helma/main/launcher/Main.java +++ b/src/helma/main/launcher/Main.java @@ -18,15 +18,20 @@ package helma.main.launcher; import java.io.File; import java.io.FilenameFilter; +import java.io.IOException; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; import java.net.URLDecoder; +import java.net.MalformedURLException; import java.util.ArrayList; /** - * Helma bootstrap class. Figures out Helma home directory, sets up class path and - * lauchnes main class. This class must be invoked from a jar file in order to work. + * Helma bootstrap class. Basically this is a convenience wrapper that takes over + * the job of setting the class path and helma install directory before launching + * the static main(String[]) method in helma.main.Server. This class + * should be invoked from a jar file in the Helma install directory in order to + * be able to set up class and install paths. */ public class Main { public static final String[] jars = { @@ -44,57 +49,39 @@ public class Main { * * @param args command line arguments * - * @throws Exception if the Helma home dir or classpath couldn't be built */ - public static void main(String[] args) throws Exception { - // check if home directory is set via command line arg. If not, - // we'll get it from the location of the jar file this class - // has been loaded from. - String installDir = null; + public static void main(String[] args) { + try { + String installDir = getInstallDir(args); - // first, try to get helma home dir from command line options - for (int i = 0; i < args.length; i++) { - if (args[i].equals("-i") && ((i + 1) < args.length)) { - installDir = args[i + 1]; - } + FilteredClassLoader loader = createClassLoader(installDir); + + // get the main server class + Class clazz = loader.loadClass("helma.main.Server"); + Class[] cargs = new Class[]{args.getClass()}; + Method main = clazz.getMethod("main", cargs); + Object[] nargs = new Object[]{args}; + + // and invoke the static main(String, String[]) method + main.invoke(null, nargs); + } catch (Exception x) { + // unable to get Helma installation dir from launcher jar + System.err.println("Unable to get Helma installation directory: "); + System.err.println(x.getMessage()); + System.exit(2); } + } - URLClassLoader apploader = (URLClassLoader) ClassLoader.getSystemClassLoader(); - // try to get Helma installation directory - if (installDir == null) { - try { - URL launcherUrl = apploader.findResource("helma/main/launcher/Main.class"); - - // this is a JAR URL of the form - // jar:!/{entry} - // we strip away the jar: prefix and the !/{entry} suffix - // to get the original jar file URL - - String jarUrl = launcherUrl.toString(); - - if (!jarUrl.startsWith("jar:") || jarUrl.indexOf("!") < 0) { - throw new RuntimeException(" Unable to get JAR URL from "+jarUrl); - } - - jarUrl = jarUrl.substring(4); - - int excl = jarUrl.indexOf("!"); - - jarUrl = jarUrl.substring(0, excl); - launcherUrl = new URL(jarUrl); - - File f = new File(launcherUrl.getPath()); - - installDir = f.getParentFile().getCanonicalPath(); - - } catch (Exception x) { - // unable to get Helma installation dir from launcher jar - System.err.println("Unable to get Helma installation directory: "); - System.err.println(x.getMessage()); - System.exit(2); - } - } + /** + * Create a Helma ClassLoader from the Helma install directory. + * + * @param installDir + * @return + * @throws MalformedURLException + */ + public static FilteredClassLoader createClassLoader(String installDir) + throws MalformedURLException { // decode installDir in case it is URL-encoded installDir = URLDecoder.decode(installDir); @@ -149,14 +136,69 @@ public class Main { // set the new class loader as context class loader Thread.currentThread().setContextClassLoader(loader); - - // get the main server class - Class clazz = loader.loadClass("helma.main.Server"); - Class[] cargs = new Class[] { args.getClass() }; - Method main = clazz.getMethod("main", cargs); - Object[] nargs = new Object[] { args }; - - // run - main.invoke(null, nargs); + return loader; } + + + /** + * Get the Helma install directory from the command line -i argument or + * from the Jar URL from which this class was loaded. Additionally, the + * System property "helma.home" is set to the install directory path. + * + * @param args + * @return + * @throws IOException + * @throws MalformedURLException + */ + public static String getInstallDir(String[] args) + throws IOException, MalformedURLException { + // check if home directory is set via command line arg. If not, + // we'll get it from the location of the jar file this class + // has been loaded from. + String installDir = null; + + // first, try to get helma home dir from command line options + for (int i = 0; i < args.length; i++) { + if (args[i].equals("-i") && ((i + 1) < args.length)) { + installDir = args[i + 1]; + } + } + + URLClassLoader apploader = (URLClassLoader) + ClassLoader.getSystemClassLoader(); + + // try to get Helma installation directory + if (installDir == null) { + URL launcherUrl = apploader.findResource("helma/main/launcher/Main.class"); + + // this is a JAR URL of the form + // jar:!/{entry} + // we strip away the jar: prefix and the !/{entry} suffix + // to get the original jar file URL + + String jarUrl = launcherUrl.toString(); + + if (!jarUrl.startsWith("jar:") || jarUrl.indexOf("!") < 0) { + throw new RuntimeException(" Unable to get JAR URL from "+jarUrl); + } + + jarUrl = jarUrl.substring(4); + + int excl = jarUrl.indexOf("!"); + + jarUrl = jarUrl.substring(0, excl); + launcherUrl = new URL(jarUrl); + + File f = new File(launcherUrl.getPath()); + + installDir = f.getParentFile().getCanonicalPath(); + + + } + // set System property + System.setProperty("helma.home", installDir); + // and return install dir + return installDir; + } + }