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