/* * JBoss, Home of Professional Open Source. * Copyright 2006, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss; import gnu.getopt.Getopt; import gnu.getopt.LongOpt; import java.io.File; import java.io.FilenameFilter; import java.net.MalformedURLException; import java.net.URL; import java.net.URLDecoder; import java.util.LinkedList; import java.util.List; import java.util.Properties; import org.jboss.system.server.Server; import org.jboss.system.server.ServerConfig; import org.jboss.system.server.ServerConfigUtil; import org.jboss.system.server.ServerLoader; /** * Provides a command line interface to start the JBoss server. *
* To enable debug or trace messages durring boot change the Log4j * configuration to use either log4j-debug.properties * log4j-trace.properties by setting the system property * log4j.configuration: * *
* ./run.sh -Dlog4j.configuration=log4j-debug.properties ** * @author Marc Fleury * @author Jason Dillon * @author Adrian Brock * @author Scott Stark * @version $Revision: 61145 $ */ public class Main { /** The JMX library to use */ private String jmxLibs = "jboss-jmx.jar"; /** EDU.oswego.cs.dl.util.concurrent */ private String concurrentLib = "concurrent.jar"; /** A URL for obtaining microkernel patches */ private URL bootURL; /** Extra jars from the /lib location that are added to the start of the boot classpath. This can be used to override jboss /lib boot classes. */ private List bootLibraries = new LinkedList(); /** Extra libraries to load the server with .*/ private List extraLibraries = new LinkedList(); /** Extra classpath URLS to load the server with .*/ private List extraClasspath = new LinkedList(); /** * Server properties. This object holds all of the required * information to get the server up and running. Use System * properties for defaults. */ private Properties props = new Properties(System.getProperties()); /** * Explicit constructor. */ public Main() { super(); } /** * Boot up JBoss. * * @param args The command line arguments. * * @throws Exception Failed to boot. */ public void boot(final String[] args) throws Exception { // First process the command line to pickup custom props/settings processCommandLine(args); // Auto set HOME_DIR to ../bin/run.jar if not set String homeDir = props.getProperty(ServerConfig.HOME_DIR); if (homeDir == null) { String path = Main.class.getProtectionDomain().getCodeSource().getLocation().getFile(); /* The 1.4 JDK munges the code source file with URL encoding so run * this path through the decoder so that is JBoss starts in a path with * spaces we don't come crashing down. */ 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); // Setup HOME_URL too, ServerLoader needs this 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); } // Load the server instance ServerLoader loader = new ServerLoader(props); /* If there is a patch dir specified make it the first element of the loader bootstrap classpath. If its a file url pointing to a dir, then add the dir and its contents. */ if (bootURL != null) { if (bootURL.getProtocol().equals("file")) { File dir = new File(bootURL.getFile()); if (dir.exists()) { // Add the local file patch directory loader.addURL(dir.toURL()); // Add the contents of the directory too 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); } } // Add any extra libraries for (int i = 0; i < bootLibraries.size(); i++) { loader.addLibrary((String)bootLibraries.get(i)); } // Add the jars from the endorsed dir loader.addEndorsedJars(); // Add jmx libs loader.addLibraries(jmxLibs); // jmx UnifiedLoaderRepository needs a concurrent class... loader.addLibrary(concurrentLib); // Add any extra libraries after the boot libs for (int i = 0; i < extraLibraries.size(); i++) { loader.addLibrary((String)extraLibraries.get(i)); } // Add any extra classapth URLs for (int i = 0; i < extraClasspath.size(); i++) { loader.addURL((URL)extraClasspath.get(i)); } // Load the server ClassLoader parentCL = Thread.currentThread().getContextClassLoader(); Server server = loader.load(parentCL); // Initialize the server server.init(props); // Start 'er up mate! server.start(); } private URL makeURL(String urlspec) throws MalformedURLException { urlspec = urlspec.trim(); URL url; try { url = new URL(urlspec); if (url.getProtocol().equals("file")) { // make sure the file is absolute & canonical file url File file = new File(url.getFile()).getCanonicalFile(); url = file.toURL(); } } catch (Exception e) { // make sure we have a absolute & canonical file url try { File file = new File(urlspec).getCanonicalFile(); url = file.toURL(); } catch (Exception n) { throw new MalformedURLException(n.toString()); } } return url; } /** Process the command line... */ private void processCommandLine(final String[] args) throws Exception { // set this from a system property or default to jboss String programName = System.getProperty("program.name", "jboss"); String sopts = "-:hD:d:p:n:c:Vj::B:L:C:P:b:g:u:l:"; 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'), new LongOpt("partition", LongOpt.REQUIRED_ARGUMENT, null, 'g'), new LongOpt("udp", LongOpt.REQUIRED_ARGUMENT, null, 'u'), new LongOpt("log", LongOpt.REQUIRED_ARGUMENT, null, 'l'), }; Getopt getopt = new Getopt(programName, args, sopts, lopts); int code; String arg; // JBAS-4119, bind to localhost by default, instead of all NICs ("0.0.0.0") props.setProperty(ServerConfig.SERVER_BIND_ADDRESS, "127.0.0.1"); System.setProperty(ServerConfig.SERVER_BIND_ADDRESS, "127.0.0.1"); while ((code = getopt.getopt()) != -1) { switch (code) { case ':': case '?': // for now both of these should exit with error status System.exit(1); break; // for completeness case 1: // this will catch non-option arguments // (which we don't currently care about) System.err.println(programName + ": unused non-option argument: " + getopt.getOptarg()); break; // for completeness case 'h': // show command line help 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
Starts up inside of a "jboss" thread group to allow better * identification of JBoss threads. * * @param args The command line arguments. */ 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(); } /** * This method is here so that if JBoss is running under * Alexandria (An NT Service Installer), Alexandria can shutdown * the system down correctly. */ 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"); } } }