View Javadoc

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             // Dain: yes this is flow control using exceptions, but I'm too lazy to add another isRegistered method to the basic registry
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         // check if service is a proxy
561         AbstractName name = proxyManager.getProxyTarget(service);
562         if (name != null) {
563             return name;
564         }
565 
566         // try the registry
567         GBeanInstance gbeanInstance = registry.getGBeanInstanceByInstance(service);
568         if (gbeanInstance != null) {
569             return gbeanInstance.getAbstractName();
570         }
571 
572         // didn't fing the name
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         // todo cleanup when boot fails
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         // load and start the kernel gbean
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 }