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.net.URL;
023    import java.util.Collection;
024    import java.util.Enumeration;
025    import java.util.Iterator;
026    import java.util.List;
027    import java.util.Set;
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.gbean.AbstractName;
033    import org.apache.geronimo.gbean.AbstractNameQuery;
034    import org.apache.geronimo.kernel.GBeanNotFoundException;
035    import org.apache.geronimo.kernel.InternalKernelException;
036    import org.apache.geronimo.kernel.Kernel;
037    import org.apache.geronimo.kernel.KernelFactory;
038    import org.apache.geronimo.kernel.config.ConfigurationData;
039    import org.apache.geronimo.kernel.config.ConfigurationManager;
040    import org.apache.geronimo.kernel.config.ConfigurationUtil;
041    import org.apache.geronimo.kernel.config.LifecycleException;
042    import org.apache.geronimo.kernel.config.NoSuchConfigException;
043    import org.apache.geronimo.kernel.config.LifecycleMonitor;
044    import org.apache.geronimo.kernel.config.DebugLoggingLifecycleMonitor;
045    import org.apache.geronimo.kernel.log.GeronimoLogging;
046    import org.apache.geronimo.kernel.repository.Artifact;
047    import org.apache.geronimo.kernel.repository.MissingDependencyException;
048    
049    
050    /**
051     * @version $Rev: 528221 $ $Date: 2007-04-12 16:22:29 -0400 (Thu, 12 Apr 2007) $
052     */
053    public class CommandLine {
054        protected static final Log log;
055    
056        static {
057            // Perform initialization tasks common with the various Geronimo environments.
058            GeronimoEnvironment.init();
059    
060            // This MUST be done before the first log is acquired
061            GeronimoLogging.initialize(GeronimoLogging.ERROR);
062            log = LogFactory.getLog(CommandLine.class.getName());
063        }
064    
065        /**
066         * Command line entry point called by executable jar
067         * @param args command line args
068         */
069        public static void main(String[] args) {
070            log.info("Server startup begun");
071            try {
072                // the interesting entries from the manifest
073                CommandLineManifest manifest = CommandLineManifest.getManifestEntries();
074                List configurations = manifest.getConfigurations();
075                AbstractNameQuery mainGBean = manifest.getMainGBeanQuery();
076                String mainMethod = manifest.getMainMethod();
077    
078                new CommandLine().invokeMainGBean(configurations, mainGBean, mainMethod, args);
079    
080                log.info("Server shutdown completed");
081            } catch (Exception e) {
082                ExceptionUtil.trimStackTrace(e);
083                e.printStackTrace();
084                System.exit(2);
085                throw new AssertionError();
086            }
087        }
088    
089        private Kernel kernel;
090        private AbstractName configurationName;
091    
092        public void invokeMainGBean(List configurations, AbstractNameQuery mainGBeanQuery, String mainMethod, String[] args) throws Exception {
093            // boot the kernel
094            kernel = getBootedKernel();
095    
096            initializeKernel();
097    
098            loadConfigurations(configurations);
099    
100            log.info("Server startup completed");
101            doInvokeMainGBean(mainGBeanQuery, mainMethod, args);
102        }
103    
104        protected void doInvokeMainGBean(AbstractNameQuery mainGBeanQuery, String mainMethod, String[] args) throws Exception {
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        protected void initializeKernel() throws Exception {
123            loadBootstrapConfiguration();
124    
125            Runtime.getRuntime().addShutdownHook(new Thread("Geronimo shutdown thread") {
126                public void run() {
127                    log.info("Server shutdown started");
128                    try {
129                        stopKernel();
130                    } catch (GBeanNotFoundException e) {
131    
132                    }
133                }
134            });
135        }
136    
137        protected void loadBootstrapConfiguration() throws Exception {
138            ClassLoader classLoader = CommandLine.class.getClassLoader();
139            InputStream in = classLoader.getResourceAsStream("META-INF/config.ser");
140            try {
141                // load the configuration
142                configurationName = ConfigurationUtil.loadBootstrapConfiguration(kernel, in, classLoader);
143            } finally {
144                if (in != null) {
145                    try {
146                        in.close();
147                    } catch (IOException ignored) {
148                        // ignored
149                    }
150                }
151            }
152        }
153    
154        protected Kernel getBootedKernel() throws Exception {
155            kernel = KernelFactory.newInstance().createKernel("geronimo");
156            kernel.boot();
157            return kernel;
158        }
159    
160        protected void startKernel(Artifact moduleId) throws Exception {
161            getBootedKernel();
162            ClassLoader classLoader = CommandLine.class.getClassLoader();
163            for (Enumeration modules = classLoader.getResources("META-INF/config.ser"); modules.hasMoreElements(); ) {
164                URL moduleDataURL = (URL) modules.nextElement();
165                InputStream in = moduleDataURL.openStream();
166                try {
167                    ConfigurationData moduleData = ConfigurationUtil.readConfigurationData(in);
168                    if (moduleId.matches(moduleData.getId())) {
169                        // load the configuration
170                        configurationName = ConfigurationUtil.loadBootstrapConfiguration(kernel, moduleData, classLoader);
171                        return;
172                    }
173                } finally {
174                    in.close();
175                }
176            }
177            throw new NoSuchConfigException(moduleId);
178        }
179    
180        protected void loadConfigurations(List configurations) throws NoSuchConfigException, LifecycleException, MissingDependencyException {
181            // load and start the configurations
182            ConfigurationManager configurationManager = ConfigurationUtil.getConfigurationManager(kernel);
183            Collection<Artifact> resolvedModules = configurationManager.getArtifactResolver().resolveInClassLoader(configurations);
184            LifecycleMonitor lifecycleMonitor = new DebugLoggingLifecycleMonitor(log);
185            try {
186                for (Artifact moduleId : resolvedModules) {
187                    configurationManager.loadConfiguration(moduleId, lifecycleMonitor);
188                    configurationManager.startConfiguration(moduleId, lifecycleMonitor);
189                }
190            } finally {
191                ConfigurationUtil.releaseConfigurationManager(kernel, configurationManager);
192            }
193        }
194    
195        protected Kernel getKernel() {
196            return kernel;
197        }
198    
199        protected void stopKernel() throws GBeanNotFoundException, InternalKernelException {
200            // stop this configuration
201            kernel.stopGBean(configurationName);
202    
203            // shutdown the kernel
204            kernel.shutdown();
205        }
206    }