Package org.apache.geronimo.system.main

Source Code of org.apache.geronimo.system.main.Daemon

/**
*
* Copyright 2003-2005 The Apache Software Foundation
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/

package org.apache.geronimo.system.main;

import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.PrintStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.geronimo.common.GeronimoEnvironment;
import org.apache.geronimo.gbean.GBeanData;
import org.apache.geronimo.gbean.GBeanQuery;
import org.apache.geronimo.kernel.Kernel;
import org.apache.geronimo.kernel.KernelFactory;
import org.apache.geronimo.kernel.config.Configuration;
import org.apache.geronimo.kernel.config.ConfigurationManager;
import org.apache.geronimo.kernel.config.ConfigurationUtil;
import org.apache.geronimo.kernel.config.ManageableAttributeStore;
import org.apache.geronimo.kernel.config.PersistentConfigurationList;
import org.apache.geronimo.kernel.log.GeronimoLogging;
import org.apache.geronimo.system.jmx.MBeanServerKernelBridge;
import org.apache.geronimo.system.serverinfo.DirectoryUtils;

/**
* @version $Rev: 356696 $ $Date: 2005-12-13 17:59:20 -0800 (Tue, 13 Dec 2005) $
*/
public class Daemon {
    private final static String ARGUMENT_NO_PROGRESS = "--quiet";
    private final static String ARGUMENT_LONG_PROGRESS = "--long";
    private final static String ARGUMENT_VERBOSE_SHORTFORM = "-v";
    private final static String ARGUMENT_VERBOSE = "--verbose";
    private final static String ARGUMENT_MORE_VERBOSE_SHORTFORM = "-vv";
    private final static String ARGUMENT_MORE_VERBOSE = "--veryverbose";
    private final static String ARGUMENT_CONFIG_OVERRIDE = "--override";
    private static boolean started = false;
    private static Log log;
    private StartupMonitor monitor;
    private List configs = new ArrayList();
    private String verboseArg = null;
    private String noProgressArg = null;
    private String longProgressArg = null;

    private Daemon(String[] args) {
        // Very first startup tasks
        long start = System.currentTimeMillis();
        // Command line arguments affect logging configuration, etc.
        if(processArguments(args)) {
            System.out.println("Booting Geronimo Kernel (in Java " + System.getProperty("java.version") + ")...");
            System.out.flush();

            // Initialization tasks that must run before anything else
            initializeSystem();

            monitor.systemStarting(start);
            doStartup();
        } else {
            System.exit(1);
            throw new AssertionError();
        }
    }

    private void printHelp(PrintStream out) {
        out.println();
        out.println("Syntax: java -jar bin/server.jar [options]");
        out.println();
        out.println("Available options are: ");
        out.println("  "+ARGUMENT_NO_PROGRESS);
        out.println("             Suppress the normal startup progress bar.  This is typically\n" +
                    "             used when redirecting console output to a file, or starting\n" +
                    "             the server from an IDE or other tool.");
        out.println("  "+ARGUMENT_LONG_PROGRESS);
        out.println("             Write startup progress to the console in a format that is\n" +
                    "             suitable for redirecting console output to a file, or starting\n" +
                    "             the server from an IDE or other tool (doesn't use linefeeds to\n" +
                    "             update the progress information that is used by default if you\n" +
                    "             don't specify " +ARGUMENT_NO_PROGRESS +" or "+ARGUMENT_LONG_PROGRESS+").\n");
        out.println("  "+ARGUMENT_VERBOSE_SHORTFORM +" " +ARGUMENT_VERBOSE);
        out.println("             Reduces the console log level to DEBUG, resulting in more\n" +
                    "             console output than is normally present.");
        out.println("  "+ARGUMENT_MORE_VERBOSE_SHORTFORM +" " +ARGUMENT_MORE_VERBOSE);
        out.println("             Reduces the console log level to TRACE, resulting in still\n" +
                    "             more console output.");
        out.println();
        out.println("  "+ARGUMENT_CONFIG_OVERRIDE+" [configId] [configId] ...");
        out.println("             USE WITH CAUTION!  Overrides the configurations in\n" +
                    "             var/config/config.xml such that only the configurations listed on\n" +
                    "             the command line will be started.  Note that many J2EE\n" +
                    "             features depend on certain configs being started, so you\n" +
                    "             should be very careful what you omit.  Any arguments after\n" +
                    "             this are assumed to be configuration names.");
        out.println();
        out.println("In addition you may specify a replacement for var/config/config.xml using by setting the property\n" +
                    "-Dorg.apache.geronimo.config.file=var/config/<my-config.xml>\n" +
                    "This is resolved relative to the geronimo base directory.");
        out.println();
    }

    /**
     * @return true if the server startup should proceed (all arguments
     *              make sense and the user didn't ask for help)
     */
    private boolean processArguments(String[] args) {
        boolean override = false;
        boolean help = false;
        for (int i = 0; i < args.length; i++) {
            if(override) {
                try {
                    configs.add(new URI(args[i]));
                } catch (URISyntaxException e) {
                    System.err.println("Invalid configuration-id: " + args[i]);
                    e.printStackTrace();
                    System.exit(1);
                    throw new AssertionError();
                }
            } else if (args[i].equals(ARGUMENT_NO_PROGRESS)) {
                noProgressArg = ARGUMENT_NO_PROGRESS;
            } else if (args[i].equals(ARGUMENT_LONG_PROGRESS)) {
                longProgressArg = ARGUMENT_LONG_PROGRESS;
            } else if (args[i].equals(ARGUMENT_VERBOSE_SHORTFORM) ||
                    args[i].equals(ARGUMENT_VERBOSE)) {
                if (verboseArg == null) {
                    verboseArg = ARGUMENT_VERBOSE;
                }
            } else if (args[i].equals(ARGUMENT_MORE_VERBOSE_SHORTFORM) ||
                    args[i].equals(ARGUMENT_MORE_VERBOSE)) {
                if (verboseArg == null) {
                    verboseArg = ARGUMENT_MORE_VERBOSE;
                }
            } else if (args[i].equals(ARGUMENT_CONFIG_OVERRIDE)) {
                override = true;
            } else if(args[i].equalsIgnoreCase("-help") || args[i].equalsIgnoreCase("--help") ||
                    args[i].equalsIgnoreCase("-h") || args[i].equalsIgnoreCase("/?")) {
                help = true;
            } else {
                System.out.println("Unrecognized argument: "+args[i]);
                help = true;
            }
        }
        if(help) {
            printHelp(System.out);
        }
        return !help;
    }

    private void initializeSystem() {
        if (!started) {
            started = true;

            // Perform initialization tasks common with the various Geronimo environments
            GeronimoEnvironment.init();

            // This MUST be done before the first log is acquired (WHICH THE STARTUP MONITOR 5 LINES LATER DOES!)
            // Generally we want to suppress anything but WARN until the log GBean starts up
            GeronimoLogging.initialize(verboseArg == null || verboseArg.equals(ARGUMENT_VERBOSE) ? GeronimoLogging.WARN : GeronimoLogging.DEBUG);
            // The following will be used once the log GBean starts up
            GeronimoLogging.setConsoleLogLevel(verboseArg == null ? GeronimoLogging.INFO : verboseArg.equals(ARGUMENT_VERBOSE) ? GeronimoLogging.DEBUG : GeronimoLogging.TRACE);
            log = LogFactory.getLog(Daemon.class.getName());
        }

        if (verboseArg != null || noProgressArg != null) {
            monitor = new SilentStartupMonitor();
        } else {
            if (longProgressArg != null)
                monitor = new LongStartupMonitor();
            else
                monitor = new ProgressBarStartupMonitor();
        }
    }

    private void doStartup() {
        try {
            // Check that the tmpdir exists - if not give friendly msg and exit
            // since we allow it to be configured in geronimo.bat and geronimo.sh
            // (since 1.0 release) the same way Tomcat allows it to be configured.
            String tmpDir = System.getProperty("java.io.tmpdir");
            if (tmpDir == null || (!(new File(tmpDir)).exists()) ||
                    (!(new File(tmpDir)).isDirectory())) {
                    System.err.println("The java.io.tmpdir system property specifies the "+
                            "non-existent directory " +tmpDir);
                    System.exit(1);
                    throw new AssertionError();
                }
           
            // Determine the geronimo installation directory
            File geronimoInstallDirectory = DirectoryUtils.getGeronimoInstallDirectory();
            if (geronimoInstallDirectory == null) {
                System.err.println("Could not determine geronimo installation directory");
                System.exit(1);
                throw new AssertionError();
            }

            // setup the endorsed dir entry
            CommandLineManifest manifestEntries = CommandLineManifest.getManifestEntries();

            String endorsedDirs = "java.endorsed.dirs";
            List endorsedDirsFromManifest = manifestEntries.getEndorsedDirs();
            AddToSystemProperty(endorsedDirs, endorsedDirsFromManifest, geronimoInstallDirectory);

            String extensionDirs = "java.ext.dirs";
            List extensionDirsFromManifest = manifestEntries.getExtensionDirs();
            AddToSystemProperty(extensionDirs, extensionDirsFromManifest, geronimoInstallDirectory);


            // load this configuration
            ClassLoader classLoader = Daemon.class.getClassLoader();
            GBeanData configuration = new GBeanData();
            ObjectInputStream ois = new ObjectInputStream(classLoader.getResourceAsStream("META-INF/config.ser"));
            try {
                configuration.readExternal(ois);
            } finally {
                ois.close();
            }
            URI configurationId = (URI) configuration.getAttribute("id");
            ObjectName configName = Configuration.getConfigurationObjectName(configurationId);
            configuration.setName(configName);

            // todo: JNB for now we clear out the dependency list but we really need a way to resolve them
            configuration.setAttribute("dependencies", Collections.EMPTY_LIST);
            configuration.setAttribute("baseURL", classLoader.getResource("/"));

            // create a mbean server
            MBeanServer mbeanServer = MBeanServerFactory.createMBeanServer("geronimo");
            String mbeanServerId = (String) mbeanServer.getAttribute(new ObjectName("JMImplementation:type=MBeanServerDelegate"), "MBeanServerId");

            // create the kernel
            final Kernel kernel = KernelFactory.newInstance().createKernel("geronimo");

            // boot the kernel
            try {
                kernel.boot();
            } catch (Exception e) {
                e.printStackTrace();
                System.exit(1);
                throw new AssertionError();
            }

            // load this configuration into the kernel
            kernel.loadGBean(configuration, classLoader);
            kernel.startGBean(configName);

            // add our shutdown hook
            Runtime.getRuntime().addShutdownHook(new Thread("Geronimo shutdown thread") {
                public void run() {
                    System.out.println("\rServer shutdown begun              ");
                    kernel.shutdown();
                    System.out.println("Server shutdown completed");
                }
            });

            // add the jmx bridge
            ObjectName mbeanServerKernelBridgeName = new ObjectName("geronimo.boot:role=MBeanServerKernelBridge");
            GBeanData mbeanServerKernelBridge = new GBeanData(mbeanServerKernelBridgeName, MBeanServerKernelBridge.GBEAN_INFO);
            mbeanServerKernelBridge.setAttribute("mbeanServerId", mbeanServerId);
            kernel.loadGBean(mbeanServerKernelBridge, classLoader);
            kernel.startGBean(mbeanServerKernelBridgeName);

            // start this configuration
            kernel.invoke(configName, "loadGBeans", new Object[]{null}, new String[]{ManageableAttributeStore.class.getName()});
            kernel.invoke(configName, "startRecursiveGBeans");
            monitor.systemStarted(kernel);

            GBeanQuery query = new GBeanQuery(null, PersistentConfigurationList.class.getName());

            if (configs.isEmpty()) {
                // --override wasn't used (nothing explicit), see what was running before
                Set configLists = kernel.listGBeans(query);
                for (Iterator i = configLists.iterator(); i.hasNext();) {
                    ObjectName configListName = (ObjectName) i.next();
                    try {
                        configs.addAll((List) kernel.invoke(configListName, "restore"));
                    } catch (IOException e) {
                        System.err.println("Unable to restore last known configurations");
                        e.printStackTrace();
                        kernel.shutdown();
                        System.exit(1);
                        throw new AssertionError();
                    }
                }
            }

            monitor.foundConfigurations((URI[]) configs.toArray(new URI[configs.size()]));

            // load the rest of the configurations
            try {
                ConfigurationManager configurationManager = ConfigurationUtil.getConfigurationManager(kernel);
                try {
                    for (Iterator i = configs.iterator(); i.hasNext();) {
                        URI configID = (URI) i.next();
                        monitor.configurationLoading(configID);
                        List list = configurationManager.loadRecursive(configID);
                        monitor.configurationLoaded(configID);
                        monitor.configurationStarting(configID);
                        for (Iterator iterator = list.iterator(); iterator.hasNext();) {
                            URI name = (URI) iterator.next();
                            configurationManager.loadGBeans(name);
                            configurationManager.start(name);
                        }
                        monitor.configurationStarted(configID);
                    }
                } finally {
                    ConfigurationUtil.releaseConfigurationManager(kernel, configurationManager);
                }
            } catch (Exception e) {
                //Exception caught when starting configurations, starting kernel shutdown
                monitor.serverStartFailed(e);
                try {
                    kernel.shutdown();
                } catch (Exception e1) {
                    System.err.println("Exception caught during kernel shutdown");
                    e1.printStackTrace();
                }
                System.exit(1);
                throw new AssertionError();
            }

            // Tell every persistent configuration list that the kernel is now fully started
            Set configLists = kernel.listGBeans(query);
            for (Iterator i = configLists.iterator(); i.hasNext();) {
                ObjectName configListName = (ObjectName) i.next();
                kernel.setAttribute(configListName, "kernelFullyStarted", Boolean.TRUE);
            }

            // Startup sequence is finished
            monitor.startupFinished();
            monitor = null;

            // capture this thread until the kernel is ready to exit
            while (kernel.isRunning()) {
                try {
                    synchronized (kernel) {
                        kernel.wait();
                    }
                } catch (InterruptedException e) {
                    // continue
                }
            }
        } catch (Exception e) {
            if (monitor != null) {
                monitor.serverStartFailed(e);
            }
            e.printStackTrace();
            System.exit(1);
            throw new AssertionError();
        }
    }

    private void AddToSystemProperty(String propertyName, List dirsFromManifest, File geronimoInstallDirectory) {
        String dirs = System.getProperty(propertyName, "");
        for (Iterator iterator = dirsFromManifest.iterator(); iterator.hasNext();) {
            String directoryName = (String) iterator.next();
            File directory = new File(directoryName);
            if (!directory.isAbsolute()) {
                directory = new File(geronimoInstallDirectory, directoryName);
            }

            if (dirs.length() > 0) {
                dirs += File.pathSeparatorChar;
            }
            dirs += directory.getAbsolutePath();
        }
        if (dirs.length() > 0) {
            System.setProperty(propertyName, dirs);
        }
        log.debug(propertyName + "=" + System.getProperty(propertyName));
    }

    /**
     * Static entry point allowing a Kernel to be run from the command line.
     *
     * Once the Kernel is booted and the configuration is loaded, the process
     * will remain running until the shutdown() method on the kernel is
     * invoked or until the JVM exits.
     *
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        new Daemon(args);
    }

}
TOP

Related Classes of org.apache.geronimo.system.main.Daemon

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.