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.File;
021 import java.io.IOException;
022 import java.util.ArrayList;
023 import java.util.Iterator;
024 import java.util.List;
025 import java.util.Set;
026
027 import org.apache.commons.logging.Log;
028 import org.apache.commons.logging.LogFactory;
029 import org.apache.geronimo.cli.daemon.DaemonCLParser;
030 import org.apache.geronimo.common.GeronimoEnvironment;
031 import org.apache.geronimo.gbean.AbstractName;
032 import org.apache.geronimo.gbean.AbstractNameQuery;
033 import org.apache.geronimo.gbean.GBeanInfo;
034 import org.apache.geronimo.gbean.GBeanInfoBuilder;
035 import org.apache.geronimo.kernel.Kernel;
036 import org.apache.geronimo.kernel.config.ConfigurationManager;
037 import org.apache.geronimo.kernel.config.ConfigurationUtil;
038 import org.apache.geronimo.kernel.config.DebugLoggingLifecycleMonitor;
039 import org.apache.geronimo.kernel.config.LifecycleMonitor;
040 import org.apache.geronimo.kernel.config.PersistentConfigurationList;
041 import org.apache.geronimo.kernel.repository.Artifact;
042 import org.apache.geronimo.kernel.util.Main;
043 import org.apache.geronimo.system.serverinfo.DirectoryUtils;
044
045
046 /**
047 * @version $Rev:385659 $ $Date: 2007-03-07 14:40:07 +1100 (Wed, 07 Mar 2007) $
048 */
049 public class EmbeddedDaemon implements Main {
050 private static final Log log = LogFactory.getLog(EmbeddedDaemon.class);
051
052 protected final Kernel kernel;
053 private StartupMonitor monitor;
054 private LifecycleMonitor lifecycleMonitor;
055 private List<Artifact> configs = new ArrayList<Artifact>();
056
057 public EmbeddedDaemon(Kernel kernel) {
058 this.kernel = kernel;
059 }
060
061 public int execute(Object opaque) {
062 if (! (opaque instanceof DaemonCLParser)) {
063 throw new IllegalArgumentException("Argument type is [" + opaque.getClass() + "]; expected [" + DaemonCLParser.class + "]");
064 }
065 DaemonCLParser parser = (DaemonCLParser) opaque;
066 initializeMonitor(parser);
067 initializeOverride(parser);
068
069 long start = System.currentTimeMillis();
070
071 System.out.println("Booting Geronimo Kernel (in Java " + System.getProperty("java.version") + ")...");
072 System.out.flush();
073
074 // Perform initialization tasks common with the various Geronimo environments
075 GeronimoEnvironment.init();
076
077 monitor.systemStarting(start);
078 return doStartup();
079 }
080
081 protected void initializeOverride(DaemonCLParser parser) {
082 String[] override = parser.getOverride();
083 if (null != override) {
084 for (String anOverride : override) {
085 configs.add(Artifact.create(anOverride));
086 }
087 }
088 }
089
090 protected void initializeMonitor(DaemonCLParser parser) {
091 if (parser.isVerboseInfo() || parser.isVerboseDebug() || parser.isVerboseTrace() || parser.isNoProgress()) {
092 monitor = new SilentStartupMonitor();
093 } else {
094 if (parser.isLongProgress()) {
095 monitor = new LongStartupMonitor();
096 } else {
097 monitor = new ProgressBarStartupMonitor();
098 }
099 }
100 lifecycleMonitor = new DebugLoggingLifecycleMonitor(log);
101 }
102
103 protected int doStartup() {
104 try {
105 // Check that the tmpdir exists - if not give friendly msg and exit
106 // since we allow it to be configured in geronimo.bat and geronimo.sh
107 // (since 1.0 release) the same way Tomcat allows it to be configured.
108 String tmpDir = System.getProperty("java.io.tmpdir");
109 if (tmpDir == null || (!(new File(tmpDir)).exists()) || (!(new File(tmpDir)).isDirectory())) {
110 System.err.println("The java.io.tmpdir system property specifies a non-existent directory: " + tmpDir);
111 return 1;
112 }
113
114 // Determine the geronimo installation directory
115 File geronimoInstallDirectory = DirectoryUtils.getGeronimoInstallDirectory();
116 if (geronimoInstallDirectory == null) {
117 System.err.println("Could not determine geronimo installation directory");
118 return 1;
119 }
120
121 int exitCode = initializeKernel();
122 if (0 != exitCode) {
123 return exitCode;
124 }
125
126 monitor.systemStarted(kernel);
127
128 AbstractNameQuery query = new AbstractNameQuery(PersistentConfigurationList.class.getName());
129
130 if (configs.isEmpty()) {
131 // --override wasn't used (nothing explicit), see what was running before
132 Set<AbstractName> configLists = kernel.listGBeans(query);
133 for (AbstractName configListName : configLists) {
134 try {
135 configs.addAll((List<Artifact>) kernel.invoke(configListName, "restore"));
136 } catch (IOException e) {
137 System.err.println("Unable to restore last known configurations");
138 e.printStackTrace();
139 shutdownKernel();
140 return 1;
141 }
142 }
143 }
144
145 monitor.foundModules(configs.toArray(new Artifact[configs.size()]));
146
147 // load the rest of the configurations
148 try {
149 ConfigurationManager configurationManager = ConfigurationUtil.getConfigurationManager(kernel);
150 try {
151 for (Artifact configID : configs) {
152 monitor.moduleLoading(configID);
153 configurationManager.loadConfiguration(configID, lifecycleMonitor);
154 monitor.moduleLoaded(configID);
155 monitor.moduleStarting(configID);
156 configurationManager.startConfiguration(configID, lifecycleMonitor);
157 monitor.moduleStarted(configID);
158 }
159 // the server has finished loading the persistent configuration so inform the gbean
160 AbstractNameQuery startedQuery = new AbstractNameQuery(ServerStatus.class.getName());
161 Set statusBeans = kernel.listGBeans(startedQuery);
162 for(Iterator itr = statusBeans.iterator();itr.hasNext();) {
163 AbstractName statusName = (AbstractName)itr.next();
164 ServerStatus status = (ServerStatus)kernel.getGBean(statusName);
165 if(status != null) {
166 status.setServerStarted(true);
167 }
168 }
169 } finally {
170 ConfigurationUtil.releaseConfigurationManager(kernel, configurationManager);
171 }
172 } catch (Exception e) {
173 //Exception caught when starting configurations, starting kernel shutdown
174 monitor.serverStartFailed(e);
175 shutdownKernel();
176 return 1;
177 }
178
179 // Tell every persistent configuration list that the kernel is now fully started
180 Set<AbstractName> configLists = kernel.listGBeans(query);
181 for (AbstractName configListName : configLists) {
182 kernel.setAttribute(configListName, "kernelFullyStarted", Boolean.TRUE);
183 }
184
185 // Startup sequence is finished
186 monitor.startupFinished();
187 monitor = null;
188
189 // capture this thread until the kernel is ready to exit
190 while (kernel.isRunning()) {
191 try {
192 synchronized (kernel) {
193 kernel.wait();
194 }
195 } catch (InterruptedException e) {
196 // continue
197 }
198 }
199 } catch (Exception e) {
200 if (monitor != null) {
201 monitor.serverStartFailed(e);
202 }
203 e.printStackTrace();
204 return 1;
205 }
206 return 0;
207 }
208
209 protected void shutdownKernel() {
210 try {
211 kernel.shutdown();
212 } catch (Exception e1) {
213 System.err.println("Exception caught during kernel shutdown");
214 e1.printStackTrace();
215 }
216 }
217
218 protected int initializeKernel() throws Exception {
219 return 0;
220 }
221
222 public static final GBeanInfo GBEAN_INFO;
223
224 static {
225 GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(EmbeddedDaemon.class, "EmbeddedDaemon");
226 infoFactory.addAttribute("kernel", Kernel.class, false);
227 infoFactory.setConstructor(new String[]{"kernel"});
228 GBEAN_INFO = infoFactory.getBeanInfo();
229 }
230
231 public static GBeanInfo getGBeanInfo() {
232 return GBEAN_INFO;
233 }
234
235 }