1 /**
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one or more
4 * contributor license agreements. See the NOTICE file distributed with
5 * this work for additional information regarding copyright ownership.
6 * The ASF licenses this file to You under the Apache License, Version 2.0
7 * (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 package org.apache.geronimo.system.main;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.geronimo.common.GeronimoEnvironment;
24 import org.apache.geronimo.gbean.AbstractName;
25 import org.apache.geronimo.gbean.AbstractNameQuery;
26 import org.apache.geronimo.kernel.Kernel;
27 import org.apache.geronimo.kernel.KernelFactory;
28 import org.apache.geronimo.kernel.config.ConfigurationManager;
29 import org.apache.geronimo.kernel.config.ConfigurationUtil;
30 import org.apache.geronimo.kernel.config.PersistentConfigurationList;
31 import org.apache.geronimo.kernel.log.GeronimoLogging;
32 import org.apache.geronimo.kernel.repository.Artifact;
33 import org.apache.geronimo.system.serverinfo.DirectoryUtils;
34
35 import java.io.File;
36 import java.io.IOException;
37 import java.io.InputStream;
38 import java.io.PrintStream;
39 import java.util.ArrayList;
40 import java.util.Iterator;
41 import java.util.List;
42 import java.util.Set;
43
44 /**
45 * @version $Rev:385659 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
46 */
47 public class Daemon {
48 private final static String ARGUMENT_NO_PROGRESS = "--quiet";
49 private final static String ARGUMENT_LONG_PROGRESS = "--long";
50 private final static String ARGUMENT_VERBOSE_SHORTFORM = "-v";
51 private final static String ARGUMENT_VERBOSE = "--verbose";
52 private final static String ARGUMENT_MORE_VERBOSE_SHORTFORM = "-vv";
53 private final static String ARGUMENT_MORE_VERBOSE = "--veryverbose";
54 private final static String ARGUMENT_MODULE_OVERRIDE = "--override";
55 private static boolean started = false;
56 private static Log log;
57 private StartupMonitor monitor;
58 private List configs = new ArrayList();
59 private String verboseArg = null;
60 private String noProgressArg = null;
61 private String longProgressArg = null;
62
63 private Daemon(String[] args) {
64
65 long start = System.currentTimeMillis();
66
67 if(processArguments(args)) {
68 System.out.println("Booting Geronimo Kernel (in Java " + System.getProperty("java.version") + ")...");
69 System.out.flush();
70
71
72 initializeSystem();
73
74 monitor.systemStarting(start);
75 doStartup();
76 } else {
77 System.exit(1);
78 throw new AssertionError();
79 }
80 }
81
82 private void printHelp(PrintStream out) {
83 out.println();
84 out.println("Syntax: java -jar bin/server.jar [options]");
85 out.println();
86 out.println("Available options are: ");
87 out.println(" "+ARGUMENT_NO_PROGRESS);
88 out.println(" Suppress the normal startup progress bar. This is typically\n" +
89 " used when redirecting console output to a file, or starting\n" +
90 " the server from an IDE or other tool.");
91 out.println(" "+ARGUMENT_LONG_PROGRESS);
92 out.println(" Write startup progress to the console in a format that is\n" +
93 " suitable for redirecting console output to a file, or starting\n" +
94 " the server from an IDE or other tool (doesn't use linefeeds to\n" +
95 " update the progress information that is used by default if you\n" +
96 " don't specify " +ARGUMENT_NO_PROGRESS +" or "+ARGUMENT_LONG_PROGRESS+").\n");
97 out.println(" "+ARGUMENT_VERBOSE_SHORTFORM +" " +ARGUMENT_VERBOSE);
98 out.println(" Reduces the console log level to DEBUG, resulting in more\n" +
99 " console output than is normally present.");
100 out.println(" "+ARGUMENT_MORE_VERBOSE_SHORTFORM +" " +ARGUMENT_MORE_VERBOSE);
101 out.println(" Reduces the console log level to TRACE, resulting in still\n" +
102 " more console output.");
103 out.println();
104 out.println(" "+ARGUMENT_MODULE_OVERRIDE+" [moduleId] [moduleId] ...");
105 out.println(" USE WITH CAUTION! Overrides the modules in\n" +
106 " var/config/config.xml such that only the modules listed on\n" +
107 " the command line will be started. Note that many J2EE\n" +
108 " features depend on certain modules being started, so you\n" +
109 " should be very careful what you omit. Any arguments after\n" +
110 " this are assumed to be module names.");
111 out.println();
112 out.println("In addition you may specify a replacement for var/config/config.xml using by setting the property\n" +
113 "-Dorg.apache.geronimo.config.file=var/config/<my-config.xml>\n" +
114 "This is resolved relative to the geronimo base directory.");
115 out.println();
116 }
117
118 /**
119 * @return true if the server startup should proceed (all arguments
120 * make sense and the user didn't ask for help)
121 */
122 private boolean processArguments(String[] args) {
123 boolean override = false;
124 boolean help = false;
125 for (int i = 0; i < args.length; i++) {
126 if(override) {
127 configs.add(Artifact.create(args[i]));
128 } else if (args[i].equals(ARGUMENT_NO_PROGRESS)) {
129 noProgressArg = ARGUMENT_NO_PROGRESS;
130 } else if (args[i].equals(ARGUMENT_LONG_PROGRESS)) {
131 longProgressArg = ARGUMENT_LONG_PROGRESS;
132 } else if (args[i].equals(ARGUMENT_VERBOSE_SHORTFORM) ||
133 args[i].equals(ARGUMENT_VERBOSE)) {
134 if (verboseArg == null) {
135 verboseArg = ARGUMENT_VERBOSE;
136 }
137 } else if (args[i].equals(ARGUMENT_MORE_VERBOSE_SHORTFORM) ||
138 args[i].equals(ARGUMENT_MORE_VERBOSE)) {
139 if (verboseArg == null) {
140 verboseArg = ARGUMENT_MORE_VERBOSE;
141 }
142 } else if (args[i].equals(ARGUMENT_MODULE_OVERRIDE)) {
143 override = true;
144 } else if(args[i].equalsIgnoreCase("-help") || args[i].equalsIgnoreCase("--help") ||
145 args[i].equalsIgnoreCase("-h") || args[i].equalsIgnoreCase("/?")) {
146 help = true;
147 } else {
148 System.out.println("Unrecognized argument: "+args[i]);
149 help = true;
150 }
151 }
152 if(help) {
153 printHelp(System.out);
154 }
155 return !help;
156 }
157
158 private void initializeSystem() {
159 if (!started) {
160 started = true;
161
162
163 GeronimoEnvironment.init();
164
165
166
167 GeronimoLogging.initialize(verboseArg == null || verboseArg.equals(ARGUMENT_VERBOSE) ? GeronimoLogging.WARN : GeronimoLogging.DEBUG);
168
169 GeronimoLogging.setConsoleLogLevel(verboseArg == null ? GeronimoLogging.INFO : verboseArg.equals(ARGUMENT_VERBOSE) ? GeronimoLogging.DEBUG : GeronimoLogging.TRACE);
170 log = LogFactory.getLog(Daemon.class.getName());
171 }
172
173 if (verboseArg != null || noProgressArg != null) {
174 monitor = new SilentStartupMonitor();
175 } else {
176 if (longProgressArg != null)
177 monitor = new LongStartupMonitor();
178 else
179 monitor = new ProgressBarStartupMonitor();
180 }
181
182
183 }
184
185 private void JVMCheck() {
186 String jvmVersion = System.getProperty("java.specification.version");
187 if (! jvmVersion.equals("1.4"))
188 log.warn("\n====================================== Warning =======================================\n" +
189 " Geronimo is currently only certified on version 1.4 of the Java Virtual Machine.\n" +
190 " Use of version " + jvmVersion + " is not currently supported. Use at your own risk.\n" +
191 " Check http://geronimo.apache.org for current information on JDK certification level.\n" +
192 "====================================== Warning =======================================");
193 }
194
195 private void doStartup() {
196 try {
197
198
199
200 String tmpDir = System.getProperty("java.io.tmpdir");
201 if (tmpDir == null || (!(new File(tmpDir)).exists()) ||
202 (!(new File(tmpDir)).isDirectory())) {
203 System.err.println("The java.io.tmpdir system property specifies the "+
204 "non-existent directory " +tmpDir);
205 System.exit(1);
206 throw new AssertionError();
207 }
208
209
210 File geronimoInstallDirectory = DirectoryUtils.getGeronimoInstallDirectory();
211 if (geronimoInstallDirectory == null) {
212 System.err.println("Could not determine geronimo installation directory");
213 System.exit(1);
214 throw new AssertionError();
215 }
216
217 ClassLoader classLoader = Daemon.class.getClassLoader();
218
219
220 final Kernel kernel = KernelFactory.newInstance().createKernel("geronimo");
221
222
223 try {
224 kernel.boot();
225 } catch (Exception e) {
226 e.printStackTrace();
227 System.exit(1);
228 throw new AssertionError();
229 }
230
231
232 Runtime.getRuntime().addShutdownHook(new Thread("Geronimo shutdown thread") {
233 public void run() {
234 System.out.println("\rServer shutdown begun ");
235 kernel.shutdown();
236 System.out.println("Server shutdown completed");
237 }
238 });
239
240
241 InputStream in = classLoader.getResourceAsStream("META-INF/config.ser");
242 try {
243 ConfigurationUtil.loadBootstrapConfiguration(kernel, in, classLoader);
244 } finally {
245 if (in != null) {
246 try {
247 in.close();
248 } catch (IOException ignored) {
249
250 }
251 }
252 }
253
254 monitor.systemStarted(kernel);
255
256 AbstractNameQuery query = new AbstractNameQuery(PersistentConfigurationList.class.getName());
257
258 if (configs.isEmpty()) {
259
260 Set configLists = kernel.listGBeans(query);
261 for (Iterator i = configLists.iterator(); i.hasNext();) {
262 AbstractName configListName = (AbstractName) i.next();
263 try {
264 configs.addAll((List) kernel.invoke(configListName, "restore"));
265 } catch (IOException e) {
266 System.err.println("Unable to restore last known configurations");
267 e.printStackTrace();
268 kernel.shutdown();
269 System.exit(1);
270 throw new AssertionError();
271 }
272 }
273 }
274
275 monitor.foundModules((Artifact[]) configs.toArray(new Artifact[configs.size()]));
276
277
278 try {
279 ConfigurationManager configurationManager = ConfigurationUtil.getConfigurationManager(kernel);
280 try {
281 for (Iterator i = configs.iterator(); i.hasNext();) {
282 Artifact configID = (Artifact) i.next();
283 monitor.moduleLoading(configID);
284 configurationManager.loadConfiguration(configID);
285 monitor.moduleLoaded(configID);
286 monitor.moduleStarting(configID);
287 configurationManager.startConfiguration(configID);
288 monitor.moduleStarted(configID);
289 }
290 } finally {
291 ConfigurationUtil.releaseConfigurationManager(kernel, configurationManager);
292 }
293 } catch (Exception e) {
294
295 monitor.serverStartFailed(e);
296 try {
297 kernel.shutdown();
298 } catch (Exception e1) {
299 System.err.println("Exception caught during kernel shutdown");
300 e1.printStackTrace();
301 }
302 System.exit(1);
303 throw new AssertionError();
304 }
305
306
307 Set configLists = kernel.listGBeans(query);
308 for (Iterator i = configLists.iterator(); i.hasNext();) {
309 AbstractName configListName = (AbstractName) i.next();
310 kernel.setAttribute(configListName, "kernelFullyStarted", Boolean.TRUE);
311 }
312
313
314 monitor.startupFinished();
315 monitor = null;
316
317
318 while (kernel.isRunning()) {
319 try {
320 synchronized (kernel) {
321 kernel.wait();
322 }
323 } catch (InterruptedException e) {
324
325 }
326 }
327 } catch (Exception e) {
328 if (monitor != null) {
329 monitor.serverStartFailed(e);
330 }
331 e.printStackTrace();
332 System.exit(1);
333 throw new AssertionError();
334 }
335 }
336
337 private void AddToSystemProperty(String propertyName, List dirsFromManifest, File geronimoInstallDirectory) {
338 String dirs = System.getProperty(propertyName, "");
339 for (Iterator iterator = dirsFromManifest.iterator(); iterator.hasNext();) {
340 String directoryName = (String) iterator.next();
341 File directory = new File(directoryName);
342 if (!directory.isAbsolute()) {
343 directory = new File(geronimoInstallDirectory, directoryName);
344 }
345
346 if (dirs.length() > 0) {
347 dirs += File.pathSeparatorChar;
348 }
349 dirs += directory.getAbsolutePath();
350 }
351 if (dirs.length() > 0) {
352 System.setProperty(propertyName, dirs);
353 }
354 log.debug(propertyName + "=" + System.getProperty(propertyName));
355 }
356
357 /**
358 * Static entry point allowing a Kernel to be run from the command line.
359 *
360 * Once the Kernel is booted and the configuration is loaded, the process
361 * will remain running until the shutdown() method on the kernel is
362 * invoked or until the JVM exits.
363 *
364 * @param args the command line arguments
365 */
366 public static void main(String[] args) {
367 new Daemon(args);
368 }
369
370 }