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 }