Overhauled server startup checks + initialization

Config can be used from Commandline.java to construct a server
that doesn't open any ports.
This commit is contained in:
stefanp 2003-12-19 17:55:30 +00:00
parent b7a1f113b5
commit ed6e4d1125
2 changed files with 314 additions and 207 deletions

View file

@ -0,0 +1,39 @@
/*
* 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 org.mortbay.util.InetAddrPort;
import java.io.File;
/**
* Utility class for server config
*/
public class Config {
InetAddrPort rmiPort = null;
InetAddrPort xmlrpcPort = null;
InetAddrPort websrvPort = null;
InetAddrPort ajp13Port = null;
File propFile = null;
File homeDir = null;
public boolean hasPortSetting() {
return (websrvPort != null || ajp13Port != null || rmiPort != null || xmlrpcPort != null);
}
}

View file

@ -88,122 +88,211 @@ public class Server implements IPathElement, Runnable {
// the XML-RPC server // the XML-RPC server
protected WebServer xmlrpc; protected WebServer xmlrpc;
/** /**
* Constructs a new Server instance with an array of command line options. * Constructs a new Server instance with an array of command line options.
*/ */
public Server(String[] args) { public Server(Config config) {
starttime = System.currentTimeMillis(); starttime = System.currentTimeMillis();
String homeDir = System.getProperty("helma.home"); rmiPort = config.rmiPort;
xmlrpcPort = config.xmlrpcPort;
websrvPort = config.websrvPort;
ajp13Port = config.ajp13Port;
hopHome = config.homeDir;
boolean usageError = false; // create system properties
sysProps = new SystemProperties(config.propFile.getAbsolutePath());
}
// file names of various property files
String propfile = null; /**
String dbPropfile = "db.properties"; * static main entry point.
String appsPropfile = null; */
public static void main(String[] args) {
checkJavaVersion();
Config config = null;
try {
config = parseArgs(args);
} catch (Exception cex) {
printUsageError(cex.toString());
System.exit(1);
}
if (!config.hasPortSetting()) {
printUsageError("no server ports set");
System.exit(1);
}
checkRunning(config);
// create new server instance
server = new Server(config);
// parse properties files etc
server.init();
// start the server main thread
server.start();
}
/**
* check if we are running on a Java 2 VM - otherwise exit with an error message
*/
public static void checkJavaVersion() {
String javaVersion = System.getProperty("java.version");
if ((javaVersion == null) || javaVersion.startsWith("1.2")
|| javaVersion.startsWith("1.1")
|| javaVersion.startsWith("1.0")) {
System.err.println("This version of Helma requires Java 1.3 or greater.");
if (javaVersion == null) { // don't think this will ever happen, but you never know
System.err.println("Your Java Runtime did not provide a version number. Please update to a more recent version.");
} else {
System.err.println("Your Java Runtime is version " + javaVersion +
". Please update to a more recent version.");
}
System.exit(1);
}
}
/**
* parse the command line arguments, read a given server.properties file
* and check the values given for server ports
* @return Config if successfull
* @throews Exception on any configuration error
*/
public static Config parseArgs(String[] args) throws Exception {
Config config = new Config();
if (System.getProperty("helma.home")!=null) {
config.homeDir = new File(System.getProperty("helma.home"));
}
// parse arguments // parse arguments
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
if (args[i].equals("-h") && ((i + 1) < args.length)) { if (args[i].equals("-h") && ((i + 1) < args.length)) {
homeDir = args[++i]; config.homeDir = new File(args[++i]);
} else if (args[i].equals("-f") && ((i + 1) < args.length)) { } else if (args[i].equals("-f") && ((i + 1) < args.length)) {
propfile = args[++i]; config.propFile = new File(args[++i]);
} else if (args[i].equals("-p") && ((i + 1) < args.length)) { } else if (args[i].equals("-p") && ((i + 1) < args.length)) {
try { try {
rmiPort = new InetAddrPort(args[++i]); config.rmiPort = new InetAddrPort(args[++i]);
} catch (Exception portx) { } catch (Exception portx) {
usageError = true; throw new Exception("Error parsing RMI server port property: " + portx);
} }
} else if (args[i].equals("-x") && ((i + 1) < args.length)) { } else if (args[i].equals("-x") && ((i + 1) < args.length)) {
try { try {
xmlrpcPort = new InetAddrPort(args[++i]); config.xmlrpcPort = new InetAddrPort(args[++i]);
} catch (Exception portx) { } catch (Exception portx) {
usageError = true; throw new Exception("Error parsing XML-RPC server port property: " + portx);
} }
} else if (args[i].equals("-w") && ((i + 1) < args.length)) { } else if (args[i].equals("-w") && ((i + 1) < args.length)) {
try { try {
websrvPort = new InetAddrPort(args[++i]); config.websrvPort = new InetAddrPort(args[++i]);
} catch (Exception portx) { } catch (Exception portx) {
usageError = true; throw new Exception("Error parsing web server port property: " + portx);
} }
} else if (args[i].equals("-jk") && ((i + 1) < args.length)) { } else if (args[i].equals("-jk") && ((i + 1) < args.length)) {
try { try {
ajp13Port = new InetAddrPort(args[++i]); config.ajp13Port = new InetAddrPort(args[++i]);
} catch (Exception portx) { } catch (Exception portx) {
usageError = true; throw new Exception("Error parsing AJP1.3 server port property: " + portx);
} }
} else if (args[i].equals("-i") && ((i + 1) < args.length)) { } else if (args[i].equals("-i") && ((i + 1) < args.length)) {
// eat away the -i parameter which is meant for helma.main.launcher.Main // eat away the -i parameter which is meant for helma.main.launcher.Main
i++; i++;
} else { } else {
System.err.println("Unknown command line token: " + args[i]); throw new Exception("Unknown command line token: " + args[i]);
usageError = true;
} }
} }
// get main property file from home dir or vice versa, depending on what we have. // get main property file from home dir or vice versa, depending on what we have.
// get property file from hopHome // get property file from hopHome
if (propfile == null) { if (config.propFile == null) {
if (homeDir != null) { if (config.homeDir != null) {
propfile = new File(homeDir, "server.properties").getAbsolutePath(); config.propFile = new File(config.homeDir, "server.properties");
} else { } else {
propfile = new File("server.properties").getAbsolutePath(); config.propFile = new File("server.properties");
} }
} }
// create system properties // create system properties
sysProps = new SystemProperties(propfile); SystemProperties sysProps = new SystemProperties(config.propFile.getAbsolutePath());
// set the log factory property
String logFactory = sysProps.getProperty("loggerFactory",
"helma.util.Logging");
helmaLogging = "helma.util.Logging".equals(logFactory);
System.setProperty("org.apache.commons.logging.LogFactory", logFactory);
// check if there's a property setting for those ports not specified via command line // check if there's a property setting for those ports not specified via command line
if ((websrvPort == null) && (sysProps.getProperty("webPort") != null)) { if ((config.websrvPort == null) && (sysProps.getProperty("webPort") != null)) {
try { try {
websrvPort = new InetAddrPort(sysProps.getProperty("webPort")); config.websrvPort = new InetAddrPort(sysProps.getProperty("webPort"));
} catch (Exception fmt) { } catch (Exception portx) {
System.err.println("Error parsing web server port property: " + fmt); throw new Exception("Error parsing web server port property from server.properties: " + portx);
} }
} }
if ((ajp13Port == null) && (sysProps.getProperty("ajp13Port") != null)) { if ((config.ajp13Port == null) && (sysProps.getProperty("ajp13Port") != null)) {
try { try {
ajp13Port = new InetAddrPort(sysProps.getProperty("ajp13Port")); config.ajp13Port = new InetAddrPort(sysProps.getProperty("ajp13Port"));
} catch (Exception fmt) { } catch (Exception portx) {
System.err.println("Error parsing AJP1.3 server port property: " + fmt); throw new Exception("Error parsing AJP1.3 server port property from server.properties: " + portx);
} }
} }
if ((rmiPort == null) && (sysProps.getProperty("rmiPort") != null)) { if ((config.rmiPort == null) && (sysProps.getProperty("rmiPort") != null)) {
try { try {
rmiPort = new InetAddrPort(sysProps.getProperty("rmiPort")); config.rmiPort = new InetAddrPort(sysProps.getProperty("rmiPort"));
} catch (Exception fmt) { } catch (Exception portx) {
System.err.println("Error parsing RMI server port property: " + fmt); throw new Exception("Error parsing RMI server port property from server.properties: " + portx);
} }
} }
if ((xmlrpcPort == null) && (sysProps.getProperty("xmlrpcPort") != null)) { if ((config.xmlrpcPort == null) && (sysProps.getProperty("xmlrpcPort") != null)) {
try { try {
xmlrpcPort = new InetAddrPort(sysProps.getProperty("xmlrpcPort")); config.xmlrpcPort = new InetAddrPort(sysProps.getProperty("xmlrpcPort"));
} catch (Exception fmt) { } catch (Exception portx) {
System.err.println("Error parsing XML-RPC server port property: " + fmt); throw new Exception("Error parsing XML-RPC server port property from server.properties: " + portx);
} }
} }
// check server ports. If no port is set, issue a warning and exit. // get hopHome from property file
if (!usageError && websrvPort == null && ajp13Port == null && if (config.homeDir == null) {
rmiPort == null && xmlrpcPort == null) { config.homeDir = new File(sysProps.getProperty("hophome"));
System.out.println(" Error: No server port specified.");
usageError = true;
} }
// if there's a usage error, output message and exit if (config.homeDir == null) {
if (usageError) { config.homeDir = new File(config.propFile.getParent());
}
// try to transform hopHome directory to its canonical representation
try {
config.homeDir = config.homeDir.getCanonicalFile();
} catch (IOException iox) {
config.homeDir = config.homeDir.getAbsoluteFile();
}
return config;
}
/**
* print the usage hints and prefix them with a message.
*/
public static void printUsageError(String msg) {
System.out.println(msg);
printUsageError();
}
/**
* print the usage hints
*/
public static void printUsageError() {
System.out.println(""); System.out.println("");
System.out.println("Usage: java helma.main.Server [options]"); System.out.println("Usage: java helma.main.Server [options]");
System.out.println("Possible options:"); System.out.println("Possible options:");
@ -221,49 +310,83 @@ public class Server implements IPathElement, Runnable {
System.out.println(""); System.out.println("");
System.err.println("Usage Error - exiting"); System.err.println("Usage Error - exiting");
System.out.println(""); System.out.println("");
System.exit(0);
} }
/**
* Check wheter a server is already running on any of the given ports
* - otherwise exit with an error message
*/
public static void checkRunning(Config config) {
// check if any of the specified server ports is in use already // check if any of the specified server ports is in use already
try { try {
if (websrvPort != null) { if (config.websrvPort != null) {
checkRunning(websrvPort); checkPort(config.websrvPort);
} }
if (rmiPort != null) { if (config.rmiPort != null) {
checkRunning(rmiPort); checkPort(config.rmiPort);
} }
if (xmlrpcPort != null) { if (config.xmlrpcPort != null) {
checkRunning(xmlrpcPort); checkPort(config.xmlrpcPort);
} }
if (ajp13Port != null) { if (config.ajp13Port != null) {
checkRunning(ajp13Port); checkPort(config.ajp13Port);
} }
} catch (Exception running) { } catch (Exception running) {
System.out.println(running.getMessage()); System.out.println(running.getMessage());
System.exit(1); System.exit(1);
} }
// get hopHome from property file
if (homeDir == null) {
homeDir = sysProps.getProperty("hophome");
} }
if (homeDir == null) {
homeDir = new File(propfile).getParent();
}
// create hopHome File object /**
hopHome = new File(homeDir); * A primitive method to check whether a server is already running on our port.
*/
private static void checkPort(InetAddrPort addrPort) throws Exception {
// checkRunning is disabled until we find a fix for the socket creation
// timeout problems reported on the list.
return;
// try to transform hopHome directory to its cononical representation /*
InetAddress addr = addrPort.getInetAddress();
if (addr == null) {
try { try {
hopHome = hopHome.getCanonicalFile(); addr = InetAddress.getLocalHost();
} catch (IOException iox) { } catch (UnknownHostException unknown) {
hopHome = hopHome.getAbsoluteFile(); System.err.println("Error checking running server: localhost is unknown.");
return;
} }
}
try {
new Socket(addr, addrPort.getPort());
} catch (IOException x) {
// we couldn't connect to the socket because no server
// is running on it yet. Everything's ok.
return;
}
// if we got so far, another server is already running on this port and db
throw new Exception("Error: Server already running on this port: " + addrPort);
*/
}
/**
* initialize the server
*/
public void init() {
// set the log factory property
String logFactory = sysProps.getProperty("loggerFactory",
"helma.util.Logging");
helmaLogging = "helma.util.Logging".equals(logFactory);
System.setProperty("org.apache.commons.logging.LogFactory", logFactory);
// set the current working directory to the helma home dir. // set the current working directory to the helma home dir.
// note that this is not a real cwd, which is not supported // note that this is not a real cwd, which is not supported
@ -285,22 +408,20 @@ public class Server implements IPathElement, Runnable {
logger.info("Setting Helma Home to " + hopHome); logger.info("Setting Helma Home to " + hopHome);
File helper = new File(hopHome, "db.properties");
dbPropfile = helper.getAbsolutePath(); // read db.properties file in helma home directory
dbProps = new SystemProperties(dbPropfile); File helper = new File(hopHome, "db.properties");
dbProps = new SystemProperties(helper.getAbsolutePath());
DbSource.setDefaultProps(dbProps); DbSource.setDefaultProps(dbProps);
appsPropfile = sysProps.getProperty("appsPropFile"); // read apps.properties file
String appsPropfile = sysProps.getProperty("appsPropFile");
if ((appsPropfile != null) && !"".equals(appsPropfile.trim())) { if ((appsPropfile != null) && !"".equals(appsPropfile.trim())) {
helper = new File(appsPropfile); helper = new File(appsPropfile);
} else { } else {
helper = new File(hopHome, "apps.properties"); helper = new File(hopHome, "apps.properties");
} }
appsProps = new SystemProperties(helper.getAbsolutePath());
appsPropfile = helper.getAbsolutePath();
appsProps = new SystemProperties(appsPropfile);
paranoid = "true".equalsIgnoreCase(sysProps.getProperty("paranoid")); paranoid = "true".equalsIgnoreCase(sysProps.getProperty("paranoid"));
@ -324,18 +445,23 @@ public class Server implements IPathElement, Runnable {
// try to load the extensions // try to load the extensions
extensions = new Vector(); extensions = new Vector();
if (sysProps.getProperty("extensions") != null) { if (sysProps.getProperty("extensions") != null) {
StringTokenizer tok = new StringTokenizer(sysProps.getProperty("extensions"), initExtensions();
","); }
}
/**
* initialize extensions
*/
private void initExtensions() {
StringTokenizer tok = new StringTokenizer(sysProps.getProperty("extensions"), ",");
while (tok.hasMoreTokens()) { while (tok.hasMoreTokens()) {
String extClassName = tok.nextToken().trim(); String extClassName = tok.nextToken().trim();
try { try {
Class extClass = Class.forName(extClassName); Class extClass = Class.forName(extClassName);
HelmaExtension ext = (HelmaExtension) extClass.newInstance(); HelmaExtension ext = (HelmaExtension) extClass.newInstance();
ext.init(this); ext.init(this);
extensions.add(ext); extensions.add(ext);
logger.info("Loaded: " + extClassName); logger.info("Loaded: " + extClassName);
@ -344,36 +470,8 @@ public class Server implements IPathElement, Runnable {
} }
} }
} }
}
/**
* static main entry point.
*/
public static void main(String[] args) {
// check if we are running on a Java 2 VM - otherwise exit with an error message
String javaVersion = System.getProperty("java.version");
if ((javaVersion == null) || javaVersion.startsWith("1.2")
|| javaVersion.startsWith("1.1")
|| javaVersion.startsWith("1.0")) {
System.err.println("This version of Helma requires Java 1.3 or greater.");
if (javaVersion == null) { // don't think this will ever happen, but you never know
System.err.println("Your Java Runtime did not provide a version number. Please update to a more recent version.");
} else {
System.err.println("Your Java Runtime is version " + javaVersion +
". Please update to a more recent version.");
}
System.exit(1);
}
// create new server instance
server = new Server(args);
// start the server main thread
server.start();
}
protected void start() { protected void start() {
// Start running, finishing setup and then entering a loop to check changes // Start running, finishing setup and then entering a loop to check changes
@ -639,37 +737,6 @@ public class Server implements IPathElement, Runnable {
return server.xmlrpc; return server.xmlrpc;
} }
/**
* A primitive method to check whether a server is already running on our port.
*/
private void checkRunning(InetAddrPort addrPort) throws Exception {
// checkRunning is disabled until we find a fix for the socket creation
// timeout problems reported on the list.
return;
/*
InetAddress addr = addrPort.getInetAddress();
if (addr == null) {
try {
addr = InetAddress.getLocalHost();
} catch (UnknownHostException unknown) {
System.err.println("Error checking running server: localhost is unknown.");
return;
}
}
try {
new Socket(addr, addrPort.getPort());
} catch (IOException x) {
// we couldn't connect to the socket because no server
// is running on it yet. Everything's ok.
return;
}
// if we got so far, another server is already running on this port and db
throw new Exception("Error: Server already running on this port: " + addrPort);
*/
}
/** /**
* *
* *
@ -785,4 +852,5 @@ public class Server implements IPathElement, Runnable {
public String getPrototype() { public String getPrototype() {
return "root"; return "root";
} }
} }