1 /**
2 *
3 * Copyright 2003-2004 The Apache Software Foundation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.geronimo.kernel.basic;
19
20 import java.util.Date;
21 import java.util.HashSet;
22 import java.util.Iterator;
23 import java.util.LinkedList;
24 import java.util.Set;
25 import javax.management.ObjectName;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.geronimo.gbean.GBeanData;
30 import org.apache.geronimo.gbean.GBeanInfo;
31 import org.apache.geronimo.gbean.AbstractNameQuery;
32 import org.apache.geronimo.gbean.AbstractName;
33 import org.apache.geronimo.gbean.runtime.GBeanInstance;
34 import org.apache.geronimo.gbean.runtime.LifecycleBroadcaster;
35 import org.apache.geronimo.kernel.DependencyManager;
36 import org.apache.geronimo.kernel.GBeanAlreadyExistsException;
37 import org.apache.geronimo.kernel.GBeanNotFoundException;
38 import org.apache.geronimo.kernel.InternalKernelException;
39 import org.apache.geronimo.kernel.Kernel;
40 import org.apache.geronimo.kernel.KernelGBean;
41 import org.apache.geronimo.kernel.KernelRegistry;
42 import org.apache.geronimo.kernel.NoSuchAttributeException;
43 import org.apache.geronimo.kernel.NoSuchOperationException;
44 import org.apache.geronimo.kernel.Jsr77Naming;
45 import org.apache.geronimo.kernel.Naming;
46 import org.apache.geronimo.kernel.management.State;
47 import org.apache.geronimo.kernel.lifecycle.LifecycleMonitor;
48 import org.apache.geronimo.kernel.proxy.ProxyManager;
49
50
51 /**
52 * The core of a Geronimo instance.
53 * A Kernel is responsible for managing the Configurations that comprise a
54 * Geronimo system and exposing them using JMX. Each Kernel is associated
55 * with an MBeanServer that is used to register the Configurations themselves
56 * and the MBeans they define.
57 * <p/>
58 * Dependencies between MBeans are handled by a dedicated DependencyManager
59 * that is responsible for tracking those dependencies and ensuring that the
60 * dependent objects follow the appropriate lifecycle and receive appropriate
61 * notifications.
62 * <p/>
63 * The Kernel also provides a ConfigurationStore which is used to stage
64 * installed Configurations (providing a local filesystem based classpath) and
65 * used hold the persistent state of each Configuration. This allows
66 * Configurations to restart in the event of system failure.
67 *
68 * TODO: Describe the order of method invocation (e.g. if loadGbean may be before boot)
69 *
70 * @version $Rev:386276 $ $Date: 2006-04-24 00:27:37 -0700 (Mon, 24 Apr 2006) $
71 */
72 public class BasicKernel implements Kernel {
73 /**
74 * Helper objects for invoke and getAttribute
75 */
76 private static final String[] NO_TYPES = new String[0];
77 private static final Object[] NO_ARGS = new Object[0];
78
79 /**
80 * Name of this kernel
81 */
82 private final String kernelName;
83
84 /**
85 * The log
86 */
87 private Log log;
88
89 /**
90 * Is this kernel running?
91 */
92 private boolean running;
93
94 /**
95 * The timestamp when the kernel was started
96 */
97 private Date bootTime;
98
99 /**
100 * The registry
101 */
102 private final BasicRegistry registry;
103
104 /**
105 * Listeners for when the kernel shutdown
106 */
107 private final LinkedList shutdownHooks = new LinkedList();
108
109 /**
110 * This manager is used by the kernel to manage dependencies between gbeans
111 */
112 private DependencyManager dependencyManager;
113
114 /**
115 * Monitors the lifecycle of all gbeans.
116 */
117 private BasicLifecycleMonitor lifecycleMonitor;
118 private LifecycleMonitor publicLifecycleMonitor;
119
120 /**
121 * This factory gbean proxies, and tracks all proxies in the system
122 */
123 private ProxyManager proxyManager;
124
125 private static final Naming INSTANCE = new Jsr77Naming();
126
127 /**
128 * Construct a Kernel with the specified name.
129 *
130 * @param kernelName the name of the kernel
131 */
132 public BasicKernel(String kernelName) {
133 if (kernelName.indexOf(':') >= 0 || kernelName.indexOf('*') >= 0 || kernelName.indexOf('?') >= 0) {
134 throw new IllegalArgumentException("Kernel name may not contain a ':', '*' or '?' character");
135 }
136 this.kernelName = kernelName;
137 this.registry = new BasicRegistry();
138 }
139
140 public String getKernelName() {
141 return kernelName;
142 }
143
144 public Naming getNaming() {
145 return INSTANCE;
146 }
147
148 /**
149 * @deprecated this will be removed as when we add generalized dependencies to gbeans... the only current user is Configuration
150 */
151 public DependencyManager getDependencyManager() {
152 return dependencyManager;
153 }
154
155 /**
156 * Gets the lifecycle monitor.
157 * @deprecated don't use this yet... it may change or go away
158 */
159 public LifecycleMonitor getLifecycleMonitor() {
160 return publicLifecycleMonitor;
161 }
162
163 /**
164 * Gets the proxy manager.
165 * @deprecated don't use this yet... it may change or go away
166 */
167 public ProxyManager getProxyManager() {
168 return proxyManager;
169 }
170
171 public Object getAttribute(ObjectName objectName, String attributeName) throws GBeanNotFoundException, NoSuchAttributeException, Exception {
172 GBeanInstance gbeanInstance = registry.getGBeanInstance(objectName);
173 return gbeanInstance.getAttribute(attributeName);
174 }
175
176 public Object getAttribute(AbstractName abstractName, String attributeName) throws GBeanNotFoundException, NoSuchAttributeException, Exception {
177 GBeanInstance gbeanInstance = registry.getGBeanInstance(abstractName);
178 return gbeanInstance.getAttribute(attributeName);
179 }
180
181 public Object getAttribute(String shortName, String attributeName) throws GBeanNotFoundException, NoSuchAttributeException, Exception {
182 return getAttribute(shortName, null, attributeName);
183 }
184
185 public Object getAttribute(Class type, String attributeName) throws GBeanNotFoundException, NoSuchAttributeException, Exception {
186 return getAttribute(null, type, attributeName);
187 }
188
189 public Object getAttribute(String shortName, Class type, String attributeName) throws GBeanNotFoundException, NoSuchAttributeException, Exception {
190 GBeanInstance gbeanInstance = registry.getGBeanInstance(shortName, type);
191 return gbeanInstance.getAttribute(attributeName);
192 }
193
194 public void setAttribute(AbstractName abstractName, String attributeName, Object attributeValue) throws GBeanNotFoundException, NoSuchAttributeException, Exception {
195 GBeanInstance gbeanInstance = registry.getGBeanInstance(abstractName);
196 gbeanInstance.setAttribute(attributeName, attributeValue);
197 }
198
199 public void setAttribute(String shortName, String attributeName, Object attributeValue) throws GBeanNotFoundException, NoSuchAttributeException, Exception {
200 setAttribute(shortName, null, attributeName, attributeValue);
201 }
202
203 public void setAttribute(Class type, String attributeName, Object attributeValue) throws GBeanNotFoundException, NoSuchAttributeException, Exception {
204 setAttribute(null, type, attributeName, attributeValue);
205 }
206
207 public void setAttribute(String shortName, Class type, String attributeName, Object attributeValue) throws GBeanNotFoundException, NoSuchAttributeException, Exception {
208 GBeanInstance gbeanInstance = registry.getGBeanInstance(shortName, type);
209 gbeanInstance.setAttribute(attributeName, attributeValue);
210 }
211
212 public Object invoke(ObjectName objectName, String methodName) throws GBeanNotFoundException, NoSuchOperationException, InternalKernelException, Exception {
213 return invoke(objectName, methodName, NO_ARGS, NO_TYPES);
214 }
215
216 public Object invoke(AbstractName abstractName, String methodName) throws GBeanNotFoundException, NoSuchOperationException, InternalKernelException, Exception {
217 return invoke(abstractName, methodName, NO_ARGS, NO_TYPES);
218 }
219
220 public Object invoke(String shortName, String methodName) throws GBeanNotFoundException, NoSuchOperationException, InternalKernelException, Exception {
221 return invoke(shortName, null, methodName, NO_ARGS, NO_TYPES);
222 }
223
224 public Object invoke(Class type, String methodName) throws GBeanNotFoundException, NoSuchOperationException, InternalKernelException, Exception {
225 return invoke(null, type, methodName, NO_ARGS, NO_TYPES);
226 }
227
228 public Object invoke(String shortName, Class type, String methodName) throws GBeanNotFoundException, NoSuchOperationException, InternalKernelException, Exception {
229 return invoke(shortName, type, methodName, NO_ARGS, NO_TYPES);
230 }
231
232 public Object invoke(ObjectName objectName, String methodName, Object[] args, String[] types) throws GBeanNotFoundException, NoSuchOperationException, InternalKernelException, Exception {
233 GBeanInstance gbeanInstance = registry.getGBeanInstance(objectName);
234 return gbeanInstance.invoke(methodName, args, types);
235 }
236
237 public Object invoke(AbstractName abstractName, String methodName, Object[] args, String[] types) throws GBeanNotFoundException, NoSuchOperationException, InternalKernelException, Exception {
238 GBeanInstance gbeanInstance = registry.getGBeanInstance(abstractName);
239 return gbeanInstance.invoke(methodName, args, types);
240 }
241
242 public Object invoke(String shortName, String methodName, Object[] args, String[] types) throws GBeanNotFoundException, NoSuchOperationException, InternalKernelException, Exception {
243 return invoke(shortName, null, methodName, args, types);
244 }
245
246 public Object invoke(Class type, String methodName, Object[] args, String[] types) throws GBeanNotFoundException, NoSuchOperationException, InternalKernelException, Exception {
247 return invoke(null, type,methodName, args, types);
248 }
249
250 public Object invoke(String shortName, Class type, String methodName, Object[] args, String[] types) throws GBeanNotFoundException, NoSuchOperationException, InternalKernelException, Exception {
251 GBeanInstance gbeanInstance = registry.getGBeanInstance(shortName, type);
252 return gbeanInstance.invoke(methodName, args, types);
253 }
254
255 public boolean isLoaded(AbstractName name) {
256 return registry.isRegistered(name);
257 }
258
259 public boolean isLoaded(String shortName) {
260 return isLoaded(shortName, null);
261 }
262
263 public boolean isLoaded(Class type) {
264 return isLoaded(null, type);
265 }
266
267 public boolean isLoaded(String shortName, Class type) {
268 try {
269 registry.getGBeanInstance(shortName, type);
270 return true;
271 } catch (GBeanNotFoundException e) {
272
273 return false;
274 }
275 }
276
277 public Object getGBean(String shortName) throws GBeanNotFoundException, InternalKernelException, IllegalStateException {
278 return getGBean(shortName, null);
279 }
280
281 public Object getGBean(Class type) throws GBeanNotFoundException, InternalKernelException, IllegalStateException {
282 return getGBean(null, type);
283 }
284
285 public Object getGBean(String shortName, Class type) throws GBeanNotFoundException, InternalKernelException, IllegalStateException {
286 GBeanInstance gbeanInstance = registry.getGBeanInstance(shortName, type);
287 if (gbeanInstance.getState() != State.RUNNING_INDEX) {
288 throw new IllegalStateException("GBean is not running: " + gbeanInstance.getAbstractName());
289 }
290 return gbeanInstance.getTarget();
291 }
292
293 public Object getGBean(ObjectName name) throws GBeanNotFoundException, InternalKernelException, IllegalStateException {
294 GBeanInstance gbeanInstance = registry.getGBeanInstance(name);
295 if (gbeanInstance.getState() != State.RUNNING_INDEX) {
296 throw new IllegalStateException("GBean is not running: " + name);
297 }
298 return gbeanInstance.getTarget();
299 }
300
301 public Object getGBean(AbstractName name) throws GBeanNotFoundException, InternalKernelException, IllegalStateException {
302 GBeanInstance gbeanInstance = registry.getGBeanInstance(name);
303 if (gbeanInstance.getState() != State.RUNNING_INDEX) {
304 throw new IllegalStateException("GBean is not running: " + name);
305 }
306 return gbeanInstance.getTarget();
307 }
308
309 public GBeanInfo getGBeanInfo(ObjectName name) throws GBeanNotFoundException {
310 GBeanInstance gbeanInstance = registry.getGBeanInstance(name);
311 return gbeanInstance.getGBeanInfo();
312 }
313
314 public GBeanInfo getGBeanInfo(AbstractName name) throws GBeanNotFoundException {
315 GBeanInstance gbeanInstance = registry.getGBeanInstance(name);
316 return gbeanInstance.getGBeanInfo();
317 }
318
319 public GBeanInfo getGBeanInfo(String shortName) throws GBeanNotFoundException {
320 return getGBeanInfo(shortName, null);
321 }
322
323 public GBeanInfo getGBeanInfo(Class type) throws GBeanNotFoundException {
324 return getGBeanInfo(null, type);
325 }
326
327 public GBeanInfo getGBeanInfo(String shortName, Class type) throws GBeanNotFoundException {
328 GBeanInstance gbeanInstance = registry.getGBeanInstance(shortName, type);
329 return gbeanInstance.getGBeanInfo();
330 }
331
332 public GBeanData getGBeanData(AbstractName name) throws GBeanNotFoundException, InternalKernelException {
333 GBeanInstance gbeanInstance = registry.getGBeanInstance(name);
334 return gbeanInstance.getGBeanData();
335 }
336
337 public GBeanData getGBeanData(String shortName) throws GBeanNotFoundException, InternalKernelException {
338 return getGBeanData(shortName, null);
339 }
340
341 public GBeanData getGBeanData(Class type) throws GBeanNotFoundException, InternalKernelException {
342 return getGBeanData(null, type);
343 }
344
345 public GBeanData getGBeanData(String shortName, Class type) throws GBeanNotFoundException, InternalKernelException {
346 GBeanInstance gbeanInstance = registry.getGBeanInstance(shortName, type);
347 return gbeanInstance.getGBeanData();
348 }
349
350 public void loadGBean(GBeanData gbeanData, ClassLoader classLoader) throws GBeanAlreadyExistsException, InternalKernelException {
351 AbstractName abstractName = gbeanData.getAbstractName();
352 Set interfaces = gbeanData.getGBeanInfo().getInterfaces();
353 LifecycleBroadcaster lifecycleBroadcaster = lifecycleMonitor.createLifecycleBroadcaster(abstractName, interfaces);
354 GBeanInstance gbeanInstance = new GBeanInstance(gbeanData, this, dependencyManager, lifecycleBroadcaster, classLoader);
355 registry.register(gbeanInstance);
356 lifecycleBroadcaster.fireLoadedEvent();
357 }
358
359 public void startGBean(AbstractName name) throws GBeanNotFoundException, InternalKernelException, IllegalStateException {
360 GBeanInstance gbeanInstance = registry.getGBeanInstance(name);
361 gbeanInstance.start();
362 }
363
364 public void startGBean(String shortName) throws GBeanNotFoundException, InternalKernelException, IllegalStateException {
365 startGBean(shortName, null);
366 }
367
368 public void startGBean(Class type) throws GBeanNotFoundException, InternalKernelException, IllegalStateException {
369 startGBean(null, type);
370 }
371
372 public void startGBean(String shortName, Class type) throws GBeanNotFoundException, InternalKernelException, IllegalStateException {
373 GBeanInstance gbeanInstance = registry.getGBeanInstance(shortName, type);
374 gbeanInstance.start();
375 }
376
377 public void startRecursiveGBean(AbstractName name) throws GBeanNotFoundException, InternalKernelException, IllegalStateException {
378 GBeanInstance gbeanInstance = registry.getGBeanInstance(name);
379 gbeanInstance.startRecursive();
380 }
381
382 public void startRecursiveGBean(String shortName) throws GBeanNotFoundException, InternalKernelException, IllegalStateException {
383 startRecursiveGBean(shortName, null);
384 }
385
386 public void startRecursiveGBean(Class type) throws GBeanNotFoundException, InternalKernelException, IllegalStateException {
387 startRecursiveGBean(null, type);
388 }
389
390 public void startRecursiveGBean(String shortName, Class type) throws GBeanNotFoundException, InternalKernelException, IllegalStateException {
391 GBeanInstance gbeanInstance = registry.getGBeanInstance(shortName, type);
392 gbeanInstance.startRecursive();
393 }
394
395 public boolean isRunning(AbstractName name) {
396 try {
397 GBeanInstance gbeanInstance = registry.getGBeanInstance(name);
398 return gbeanInstance.getState() == State.RUNNING_INDEX;
399 } catch (GBeanNotFoundException e) {
400 return false;
401 }
402 }
403
404 public boolean isRunning(String shortName) {
405 return isRunning(shortName, null);
406 }
407
408 public boolean isRunning(Class type) {
409 return isRunning(null, type);
410 }
411
412 public boolean isRunning(String shortName, Class type) {
413 try {
414 GBeanInstance gbeanInstance = registry.getGBeanInstance(shortName, type);
415 return gbeanInstance.getState() == State.RUNNING_INDEX;
416 } catch (GBeanNotFoundException e) {
417 return false;
418 }
419 }
420
421 public void stopGBean(AbstractName name) throws GBeanNotFoundException, InternalKernelException, IllegalStateException {
422 GBeanInstance gbeanInstance = registry.getGBeanInstance(name);
423 gbeanInstance.stop();
424 }
425
426 public void stopGBean(String shortName) throws GBeanNotFoundException, InternalKernelException, IllegalStateException {
427 stopGBean(shortName, null);
428 }
429
430 public void stopGBean(Class type) throws GBeanNotFoundException, InternalKernelException, IllegalStateException {
431 stopGBean(null, type);
432 }
433
434 public void stopGBean(String shortName, Class type) throws GBeanNotFoundException, InternalKernelException, IllegalStateException {
435 GBeanInstance gbeanInstance = registry.getGBeanInstance(shortName, type);
436 gbeanInstance.stop();
437 }
438
439 public void unloadGBean(AbstractName name) throws GBeanNotFoundException, InternalKernelException, IllegalStateException {
440 GBeanInstance gbeanInstance = registry.getGBeanInstance(name);
441 gbeanInstance.die();
442 registry.unregister(name);
443 }
444
445 public void unloadGBean(String shortName) throws GBeanNotFoundException, InternalKernelException, IllegalStateException {
446 unloadGBean(shortName, null);
447 }
448
449 public void unloadGBean(Class type) throws GBeanNotFoundException, InternalKernelException, IllegalStateException {
450 unloadGBean(null, type);
451 }
452
453 public void unloadGBean(String shortName, Class type) throws GBeanNotFoundException, InternalKernelException, IllegalStateException {
454 GBeanInstance gbeanInstance = registry.getGBeanInstance(shortName, type);
455 AbstractName name = gbeanInstance.getAbstractName();
456 gbeanInstance.die();
457 registry.unregister(name);
458 }
459
460 public int getGBeanState(ObjectName name) throws GBeanNotFoundException {
461 GBeanInstance gbeanInstance = registry.getGBeanInstance(name);
462 return gbeanInstance.getState();
463 }
464
465 public int getGBeanState(AbstractName name) throws GBeanNotFoundException {
466 GBeanInstance gbeanInstance = registry.getGBeanInstance(name);
467 return gbeanInstance.getState();
468 }
469
470 public int getGBeanState(String shortName) throws GBeanNotFoundException {
471 return getGBeanState(shortName, null);
472 }
473
474 public int getGBeanState(Class type) throws GBeanNotFoundException {
475 return getGBeanState(null, type);
476 }
477
478 public int getGBeanState(String shortName, Class type) throws GBeanNotFoundException {
479 GBeanInstance gbeanInstance = registry.getGBeanInstance(shortName, type);
480 return gbeanInstance.getState();
481 }
482
483 public long getGBeanStartTime(AbstractName name) throws GBeanNotFoundException {
484 GBeanInstance gbeanInstance = registry.getGBeanInstance(name);
485 return gbeanInstance.getStartTime();
486 }
487
488 public long getGBeanStartTime(String shortName) throws GBeanNotFoundException {
489 return getGBeanStartTime(shortName, null);
490 }
491
492 public long getGBeanStartTime(Class type) throws GBeanNotFoundException {
493 return getGBeanStartTime(null, type);
494 }
495
496 public long getGBeanStartTime(String shortName, Class type) throws GBeanNotFoundException {
497 GBeanInstance gbeanInstance = registry.getGBeanInstance(shortName, type);
498 return gbeanInstance.getStartTime();
499 }
500
501 public Set listGBeans(ObjectName pattern) {
502 Set gbeans = registry.listGBeans(pattern);
503
504 Set result = new HashSet(gbeans.size());
505 for (Iterator i = gbeans.iterator(); i.hasNext();) {
506 GBeanInstance instance = (GBeanInstance) i.next();
507 result.add(instance.getObjectNameObject());
508 }
509 return result;
510 }
511
512 public Set listGBeans(Set patterns) {
513 Set gbeans = new HashSet();
514 for (Iterator iterator = patterns.iterator(); iterator.hasNext();) {
515 Object pattern = iterator.next();
516 if (pattern instanceof ObjectName) {
517 gbeans.addAll(listGBeans((ObjectName)pattern));
518 } else if (pattern instanceof AbstractNameQuery) {
519 gbeans.addAll(listGBeans((AbstractNameQuery)pattern));
520 }
521 }
522 return gbeans;
523 }
524
525 public Set listGBeans(AbstractNameQuery query) {
526 Set gbeans = registry.listGBeans(query);
527 Set result = new HashSet(gbeans.size());
528 for (Iterator i = gbeans.iterator(); i.hasNext();) {
529 GBeanInstance instance = (GBeanInstance) i.next();
530 result.add(instance.getAbstractName());
531 }
532 return result;
533 }
534
535 public Set listGBeansByInterface(String[] interfaces) {
536 Set gbeans = new HashSet();
537 Set all = listGBeans((AbstractNameQuery)null);
538 for (Iterator it = all.iterator(); it.hasNext();) {
539 AbstractName name = (AbstractName) it.next();
540 try {
541 GBeanInfo info = getGBeanInfo(name);
542 Set intfs = info.getInterfaces();
543 for (int i = 0; i < interfaces.length; i++) {
544 String candidate = interfaces[i];
545 if(intfs.contains(candidate)) {
546 gbeans.add(name);
547 break;
548 }
549 }
550 } catch (GBeanNotFoundException e) {}
551 }
552 return gbeans;
553 }
554
555 public AbstractName getAbstractNameFor(Object service) {
556 if(!running) {
557 return null;
558 }
559
560
561 AbstractName name = proxyManager.getProxyTarget(service);
562 if (name != null) {
563 return name;
564 }
565
566
567 GBeanInstance gbeanInstance = registry.getGBeanInstanceByInstance(service);
568 if (gbeanInstance != null) {
569 return gbeanInstance.getAbstractName();
570 }
571
572
573 return null;
574 }
575
576 public String getShortNameFor(Object service) {
577 AbstractName name = getAbstractNameFor(service);
578 if (name != null) {
579 return (String) name.getName().get("name");
580 }
581 return null;
582 }
583
584 /**
585 * Boot this Kernel, triggering the instantiation of the MBeanServer and DependencyManager,
586 * and the registration of ConfigurationStore
587 *
588 * @throws java.lang.Exception if the boot fails
589 */
590 public void boot() throws Exception {
591 if (running) {
592 return;
593 }
594 bootTime = new Date();
595 log = LogFactory.getLog(BasicKernel.class.getName());
596 log.debug("Starting boot");
597
598
599 KernelRegistry.registerKernel(this);
600
601 registry.start(this);
602
603 lifecycleMonitor = new BasicLifecycleMonitor(this);
604 publicLifecycleMonitor = new LifecycleMonitorFlyweight(lifecycleMonitor);
605 dependencyManager = new BasicDependencyManager(publicLifecycleMonitor);
606 proxyManager = new BasicProxyManager(this);
607
608
609 GBeanData kernelGBeanData = new GBeanData(KERNEL_NAME, KernelGBean.GBEAN_INFO);
610 loadGBean(kernelGBeanData, getClass().getClassLoader());
611 startGBean(KERNEL_NAME);
612
613 running = true;
614 log.debug("Booted");
615 }
616
617 public Date getBootTime() {
618 return bootTime;
619 }
620
621 public void registerShutdownHook(Runnable hook) {
622 assert hook != null : "Shutdown hook was null";
623 synchronized (shutdownHooks) {
624 shutdownHooks.add(hook);
625 }
626 }
627
628 public void unregisterShutdownHook(Runnable hook) {
629 synchronized (shutdownHooks) {
630 shutdownHooks.remove(hook);
631 }
632 }
633
634 /**
635 * Shut down this kernel instance, unregistering the MBeans and releasing
636 * the MBeanServer.
637 */
638 public void shutdown() {
639 if (!running) {
640 return;
641 }
642 running = false;
643 log.debug("Starting kernel shutdown");
644
645 notifyShutdownHooks();
646
647 registry.stop();
648
649 dependencyManager.close();
650 dependencyManager = null;
651
652 synchronized (this) {
653 notify();
654 }
655
656 KernelRegistry.unregisterKernel(this);
657
658 log.debug("Kernel shutdown complete");
659 }
660
661 private void notifyShutdownHooks() {
662 while (!shutdownHooks.isEmpty()) {
663 Runnable hook;
664 synchronized (shutdownHooks) {
665 hook = (Runnable) shutdownHooks.removeFirst();
666 }
667 try {
668 hook.run();
669 } catch (Throwable e) {
670 log.warn("Error from kernel shutdown hook", e);
671 }
672 }
673 }
674
675 public boolean isRunning() {
676 return running;
677 }
678
679 public ClassLoader getClassLoaderFor(AbstractName name) throws GBeanNotFoundException {
680 GBeanInstance gbeanInstance = registry.getGBeanInstance(name);
681 return gbeanInstance.getClassLoader();
682 }
683
684 public ClassLoader getClassLoaderFor(String shortName) throws GBeanNotFoundException {
685 return getClassLoaderFor(shortName, null);
686 }
687
688 public ClassLoader getClassLoaderFor(Class type) throws GBeanNotFoundException {
689 return getClassLoaderFor(null, type);
690 }
691
692 public ClassLoader getClassLoaderFor(String shortName, Class type) throws GBeanNotFoundException {
693 GBeanInstance gbeanInstance = registry.getGBeanInstance(shortName, type);
694 return gbeanInstance.getClassLoader();
695 }
696
697 /**
698 * @deprecated Experimental feature
699 */
700 public String getStateReason(AbstractName abstractName) {
701 try {
702 GBeanInstance gbeanInstance = registry.getGBeanInstance(abstractName);
703 return gbeanInstance.getStateReason();
704 } catch (GBeanNotFoundException e) {
705 return null;
706 }
707 }
708 }