package org.jboss;
import java.io.File;
import java.io.FilenameFilter;
import java.net.URL;
import java.net.URLDecoder;
import java.net.MalformedURLException;
import java.util.Properties;
import java.util.List;
import java.util.LinkedList;
import gnu.getopt.Getopt;
import gnu.getopt.LongOpt;
import org.jboss.system.server.Server;
import org.jboss.system.server.ServerConfig;
import org.jboss.system.server.ServerConfigUtil;
import org.jboss.system.server.ServerLoader;
public class Main
{
private String jaxpLibs = null;
private String jmxLibs = "jboss-jmx.jar,dom4j.jar,jaxen.jar,gnu-regexp.jar";
private String concurrentLib = "concurrent.jar";
private URL bootURL;
private List bootLibraries = new LinkedList();
private List extraLibraries = new LinkedList();
private List extraClasspath = new LinkedList();
private Properties props = new Properties(System.getProperties());
public Main()
{
super();
}
public void boot(final String[] args) throws Exception
{
processCommandLine(args);
String homeDir = props.getProperty(ServerConfig.HOME_DIR);
if (homeDir == null)
{
String path = Main.class.getProtectionDomain().getCodeSource().getLocation().getFile();
path = URLDecoder.decode(path, "UTF-8");
File runJar = new File(path);
File homeFile = runJar.getParentFile().getParentFile();
homeDir = homeFile.getCanonicalPath();
}
props.setProperty(ServerConfig.HOME_DIR, homeDir);
String homeURL = props.getProperty(ServerConfig.HOME_URL);
if (homeURL == null)
{
File file = new File(homeDir);
homeURL = file.toURL().toString();
props.setProperty(ServerConfig.HOME_URL, homeURL);
}
ServerLoader loader = new ServerLoader(props);
if (bootURL != null)
{
if (bootURL.getProtocol().equals("file"))
{
File dir = new File(bootURL.getFile());
if (dir.exists())
{
loader.addURL(dir.toURL());
File[] jars = dir.listFiles(new JarFilter());
for (int j = 0; jars != null && j < jars.length; j++)
{
loader.addURL(jars[j].getCanonicalFile().toURL());
}
}
}
else
{
loader.addURL(bootURL);
}
}
for (int i = 0; i < bootLibraries.size(); i++)
{
loader.addLibrary((String)bootLibraries.get(i));
}
if (jaxpLibs != null)
loader.addLibraries(jaxpLibs);
loader.addEndorsedJars();
loader.addLibraries(jmxLibs);
loader.addLibrary(concurrentLib);
for (int i = 0; i < extraLibraries.size(); i++)
{
loader.addLibrary((String)extraLibraries.get(i));
}
for (int i = 0; i < extraClasspath.size(); i++)
{
loader.addURL((URL)extraClasspath.get(i));
}
ClassLoader parentCL = Thread.currentThread().getContextClassLoader();
Server server = loader.load(parentCL);
server.init(props);
ServerConfig config = server.getConfig();
config.setExitOnShutdown(true);
server.start();
}
private URL makeURL(String urlspec) throws MalformedURLException
{
urlspec = urlspec.trim();
URL url;
try
{
url = new URL(urlspec);
if (url.getProtocol().equals("file"))
{
File file = new File(url.getFile()).getCanonicalFile();
url = file.toURL();
}
}
catch (Exception e)
{
try
{
File file = new File(urlspec).getCanonicalFile();
url = file.toURL();
}
catch (Exception n)
{
throw new MalformedURLException(n.toString());
}
}
return url;
}
private void processCommandLine(final String[] args) throws Exception
{
String programName = System.getProperty("program.name", "jboss");
String sopts = "-:hD:d:p:n:c:Vj:B:L:C:P:b:";
LongOpt[] lopts =
{
new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h'),
new LongOpt("bootdir", LongOpt.REQUIRED_ARGUMENT, null, 'd'),
new LongOpt("patchdir", LongOpt.REQUIRED_ARGUMENT, null, 'p'),
new LongOpt("netboot", LongOpt.REQUIRED_ARGUMENT, null, 'n'),
new LongOpt("configuration", LongOpt.REQUIRED_ARGUMENT, null, 'c'),
new LongOpt("version", LongOpt.NO_ARGUMENT, null, 'V'),
new LongOpt("jaxp", LongOpt.REQUIRED_ARGUMENT, null, 'j'),
new LongOpt("bootlib", LongOpt.REQUIRED_ARGUMENT, null, 'B'),
new LongOpt("library", LongOpt.REQUIRED_ARGUMENT, null, 'L'),
new LongOpt("classpath", LongOpt.REQUIRED_ARGUMENT, null, 'C'),
new LongOpt("properties", LongOpt.REQUIRED_ARGUMENT, null, 'P'),
new LongOpt("host", LongOpt.REQUIRED_ARGUMENT, null, 'b'),
};
Getopt getopt = new Getopt(programName, args, sopts, lopts);
int code;
String arg;
props.setProperty(ServerConfig.SERVER_BIND_ADDRESS, "0.0.0.0");
System.setProperty(ServerConfig.SERVER_BIND_ADDRESS, "0.0.0.0");
while ((code = getopt.getopt()) != -1)
{
switch (code)
{
case ':':
case '?':
System.exit(1);
break;
case 1:
System.err.println(programName +
": unused non-option argument: " +
getopt.getOptarg());
break;
case 'h':
System.out.println("usage: " + programName + " [options]");
System.out.println();
System.out.println("options:");
System.out.println(" -h, --help Show this help message");
System.out.println(" -V, --version Show version information");
System.out.println(" -- Stop processing options");
System.out.println(" -D<name>[=<value>] Set a system property");
System.out.println(" -d, --bootdir=<dir> Set the boot patch directory; Must be absolute or url");
System.out.println(" -p, --patchdir=<dir> Set the patch directory; Must be absolute or url");
System.out.println(" -n, --netboot=<url> Boot from net with the given url as base");
System.out.println(" -c, --configuration=<name> Set the server configuration name");
System.out.println(" -j, --jaxp=<type> Set the JAXP impl type (ie. crimson)");
System.out.println(" -B, --bootlib=<filename> Add an extra library to the front bootclasspth");
System.out.println(" -L, --library=<filename> Add an extra library to the loaders classpath");
System.out.println(" -C, --classpath=<url> Add an extra url to the loaders classpath");
System.out.println(" -P, --properties=<url> Load system properties from the given url");
System.out.println(" -b, --host=<host or ip> Bind address for all JBoss services");
System.out.println();
System.exit(0);
break;
case 'D':
{
arg = getopt.getOptarg();
String name, value;
int i = arg.indexOf("=");
if (i == -1)
{
name = arg;
value = "true";
}
else
{
name = arg.substring(0, i);
value = arg.substring(i + 1, arg.length());
}
System.setProperty(name, value);
break;
}
case 'd':
bootURL = makeURL(getopt.getOptarg());
break;
case 'p':
{
URL patchURL = makeURL(getopt.getOptarg());
props.put(ServerConfig.PATCH_URL, patchURL.toString());
break;
}
case 'n':
arg = getopt.getOptarg();
if (!arg.endsWith("/")) arg += "/";
props.put(ServerConfig.HOME_URL, new URL(arg).toString());
break;
case 'c':
arg = getopt.getOptarg();
props.put(ServerConfig.SERVER_NAME, arg);
break;
case 'V':
{
Package jbossPackage = Package.getPackage("org.jboss");
System.out.println("JBoss " + jbossPackage.getImplementationVersion());
System.out.println();
System.out.println("Distributable under LGPL license.");
System.out.println("See terms of license at gnu.org.");
System.out.println();
System.exit(0);
break; }
case 'j':
{
arg = getopt.getOptarg().toLowerCase();
String domFactoryType, saxFactoryType;
if (arg.equals("crimson"))
{
domFactoryType = "org.apache.crimson.jaxp.DocumentBuilderFactoryImpl";
saxFactoryType = "org.apache.crimson.jaxp.SAXParserFactoryImpl";
jaxpLibs = "crimson.jar";
}
else if (arg.equals("xerces"))
{
domFactoryType = "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl";
saxFactoryType = "org.apache.xerces.jaxp.SAXParserFactoryImpl";
jaxpLibs = "xercesImpl.jar,xml-apis.jar,resolver.jar";
}
else
{
System.err.println("Invalid JAXP type: " + arg + " (Expected 'crimson' or 'xerces')");
System.exit(1);
break;
}
System.setProperty("javax.xml.parsers.DocumentBuilderFactory", domFactoryType);
System.setProperty("javax.xml.parsers.SAXParserFactory", saxFactoryType);
break;
}
case 'B':
arg = getopt.getOptarg();
bootLibraries.add(arg);
break;
case 'L':
arg = getopt.getOptarg();
extraLibraries.add(arg);
break;
case 'C':
{
URL url = makeURL(getopt.getOptarg());
extraClasspath.add(url);
break;
}
case 'P':
{
URL url = makeURL(getopt.getOptarg());
Properties props = System.getProperties();
props.load(url.openConnection().getInputStream());
break;
}
case 'b':
arg = getopt.getOptarg();
props.put(ServerConfig.SERVER_BIND_ADDRESS, arg);
System.setProperty(ServerConfig.SERVER_BIND_ADDRESS, arg);
System.setProperty("bind.address", arg);
String rmiHost = System.getProperty("java.rmi.server.hostname");
if( rmiHost == null )
{
rmiHost = ServerConfigUtil.fixRemoteAddress(arg);
System.setProperty("java.rmi.server.hostname", rmiHost);
}
break;
default:
throw new Error("unhandled option code: " + code);
}
}
}
public static void main(final String[] args) throws Exception
{
Runnable worker = new Runnable() {
public void run()
{
try
{
Main main = new Main();
main.boot(args);
}
catch (Exception e)
{
System.err.println("Failed to boot JBoss:");
e.printStackTrace();
}
}
};
ThreadGroup threads = new ThreadGroup("jboss");
new Thread(threads, worker, "main").start();
}
public static void systemExit(String argv[])
{
System.exit(0);
}
static class JarFilter implements FilenameFilter
{
public boolean accept(File dir, String name)
{
return name.endsWith(".jar");
}
}
}