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