001    /**
002     *
003     *  Licensed to the Apache Software Foundation (ASF) under one or more
004     *  contributor license agreements.  See the NOTICE file distributed with
005     *  this work for additional information regarding copyright ownership.
006     *  The ASF licenses this file to You under the Apache License, Version 2.0
007     *  (the "License"); you may not use this file except in compliance with
008     *  the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     *  Unless required by applicable law or agreed to in writing, software
013     *  distributed under the License is distributed on an "AS IS" BASIS,
014     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     *  See the License for the specific language governing permissions and
016     *  limitations under the License.
017     */
018    
019    package org.apache.geronimo.system.main;
020    
021    import java.io.IOException;
022    import java.io.InputStream;
023    import java.util.Iterator;
024    import java.util.List;
025    import java.util.Enumeration;
026    import java.util.Set;
027    import java.util.Collection;
028    import java.net.URL;
029    
030    import org.apache.commons.logging.Log;
031    import org.apache.commons.logging.LogFactory;
032    import org.apache.geronimo.common.GeronimoEnvironment;
033    import org.apache.geronimo.kernel.GBeanNotFoundException;
034    import org.apache.geronimo.kernel.InternalKernelException;
035    import org.apache.geronimo.kernel.Kernel;
036    import org.apache.geronimo.kernel.KernelFactory;
037    import org.apache.geronimo.kernel.config.ConfigurationManager;
038    import org.apache.geronimo.kernel.config.ConfigurationUtil;
039    import org.apache.geronimo.kernel.config.NoSuchConfigException;
040    import org.apache.geronimo.kernel.config.LifecycleException;
041    import org.apache.geronimo.kernel.config.ConfigurationData;
042    import org.apache.geronimo.kernel.log.GeronimoLogging;
043    import org.apache.geronimo.kernel.repository.Artifact;
044    import org.apache.geronimo.kernel.repository.MissingDependencyException;
045    import org.apache.geronimo.gbean.AbstractName;
046    import org.apache.geronimo.gbean.AbstractNameQuery;
047    
048    
049    /**
050     * @version $Rev: 470597 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
051     */
052    public class CommandLine {
053        protected static final Log log;
054    
055        static {
056            // Perform initialization tasks common with the various Geronimo environments.
057            GeronimoEnvironment.init();
058    
059            // This MUST be done before the first log is acquired
060            GeronimoLogging.initialize(GeronimoLogging.ERROR);
061            log = LogFactory.getLog(CommandLine.class.getName());
062        }
063    
064        /**
065         * Command line entry point called by executable jar
066         * @param args command line args
067         */
068        public static void main(String[] args) {
069            log.info("Server startup begun");
070            try {
071                // the interesting entries from the manifest
072                CommandLineManifest manifest = CommandLineManifest.getManifestEntries();
073                List configurations = manifest.getConfigurations();
074                AbstractNameQuery mainGBean = manifest.getMainGBeanQuery();
075                String mainMethod = manifest.getMainMethod();
076    
077                new CommandLine().invokeMainGBean(configurations, mainGBean, mainMethod, args);
078    
079                log.info("Server shutdown completed");
080            } catch (Exception e) {
081                ExceptionUtil.trimStackTrace(e);
082                e.printStackTrace();
083                System.exit(2);
084                throw new AssertionError();
085            }
086        }
087    
088        private Kernel kernel;
089        private AbstractName configurationName;
090    
091        public void invokeMainGBean(List configurations, AbstractNameQuery mainGBeanQuery, String mainMethod, String[] args) throws Exception {
092            startKernel();
093            Runtime.getRuntime().addShutdownHook(new Thread("Geronimo shutdown thread") {
094                public void run() {
095                    log.info("Server shutdown begun");
096                    try {
097                        stopKernel();
098                    } catch (GBeanNotFoundException e) {
099    
100                    }
101                }
102            });
103            loadConfigurations(configurations);
104    
105            log.info("Server startup completed");
106            Set matches = kernel.listGBeans(mainGBeanQuery);
107            if (matches.isEmpty()) {
108                throw new Exception("No match for AbstractNameQuery: " + mainGBeanQuery);
109            }
110            if (matches.size() > 1) {
111                throw new Exception("Ambiguous AbstractNameQuery: " + mainGBeanQuery + " matches: " + matches);
112            }
113            AbstractName mainGBean = (AbstractName) matches.iterator().next();
114    
115            // invoke the main method
116            kernel.invoke(
117                    mainGBean,
118                    mainMethod,
119                    new Object[]{args},
120                    new String[]{String[].class.getName()});
121    
122        }
123    
124        protected void startKernel() throws Exception {
125            ClassLoader classLoader = CommandLine.class.getClassLoader();
126            InputStream in = classLoader.getResourceAsStream("META-INF/config.ser");
127            try {
128                // boot the kernel
129                kernel = KernelFactory.newInstance().createKernel("geronimo");
130                kernel.boot();
131        
132                // load the configuration
133                configurationName = ConfigurationUtil.loadBootstrapConfiguration(kernel, in, classLoader);
134            } finally {
135                if (in != null) {
136                    try {
137                        in.close();
138                    } catch (IOException ignored) {
139                        // ignored
140                    }
141                }
142            }
143        }
144    
145        protected void startKernel(Artifact moduleId) throws Exception {
146            // boot the kernel
147            kernel = KernelFactory.newInstance().createKernel("geronimo");
148            kernel.boot();
149            ClassLoader classLoader = CommandLine.class.getClassLoader();
150            for (Enumeration modules = classLoader.getResources("META-INF/config.ser"); modules.hasMoreElements(); ) {
151                URL moduleDataURL = (URL) modules.nextElement();
152                InputStream in = moduleDataURL.openStream();
153                try {
154                    ConfigurationData moduleData = ConfigurationUtil.readConfigurationData(in);
155                    if (moduleId.matches(moduleData.getId())) {
156                        // load the configuration
157                        configurationName = ConfigurationUtil.loadBootstrapConfiguration(kernel, moduleData, classLoader);
158                        return;
159                    }
160                } finally {
161                    in.close();
162                }
163            }
164            throw new NoSuchConfigException(moduleId);
165        }
166    
167        protected void loadConfigurations(List configurations) throws NoSuchConfigException, LifecycleException, MissingDependencyException {
168            // load and start the configurations
169            ConfigurationManager configurationManager = ConfigurationUtil.getConfigurationManager(kernel);
170            Collection resolvedConfigurations = configurationManager.getArtifactResolver().resolveInClassLoader(configurations);
171            try {
172                for (Iterator i = resolvedConfigurations.iterator(); i.hasNext();) {
173                    Artifact configID = (Artifact) i.next();
174                    configurationManager.loadConfiguration(configID);
175                    configurationManager.startConfiguration(configID);
176                }
177            } finally {
178                ConfigurationUtil.releaseConfigurationManager(kernel, configurationManager);
179            }
180        }
181    
182        protected Kernel getKernel() {
183            return kernel;
184        }
185    
186        protected void stopKernel() throws GBeanNotFoundException, InternalKernelException {
187            // stop this configuration
188            kernel.stopGBean(configurationName);
189    
190            // shutdown the kernel
191            kernel.shutdown();
192        }
193    }