blob: 77d87d6490ba6536ce5db3aa50143a68ef314e5d [file] [log] [blame]
/**
*
* Copyright 2005 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gbean.kernel;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.management.ObjectName;
import org.gbean.kernel.simple.SimpleServiceFactory;
import org.gbean.loader.LoaderUtil;
import org.gbean.spring.FatalStartupError;
/**
* @version $Revision$ $Date$
*/
public class KernelMain implements Main {
private static final String DEFAULT_KERNEL_NAME = "gbean";
private Kernel kernel;
private ClassLoader classLoader;
private Map services = Collections.EMPTY_MAP;
private List locations = Collections.EMPTY_LIST;
private boolean daemon = true;
private Main next;
public Kernel getKernel() {
return kernel;
}
public void setKernel(Kernel kernel) {
this.kernel = kernel;
}
public ClassLoader getClassLoader() {
return classLoader;
}
public void setClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
public Map getServices() {
return services;
}
public void setServices(Map services) {
this.services = services;
}
public List getLocations() {
return locations;
}
public void setLocations(List locations) {
this.locations = locations;
}
public boolean isDaemon() {
return daemon;
}
public void setDaemon(boolean daemon) {
this.daemon = daemon;
}
public Main getNext() {
return next;
}
public void setNext(Main next) {
this.next = next;
}
public void main(String[] args) {
if (classLoader == null) {
classLoader = Thread.currentThread().getContextClassLoader();
}
ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(classLoader);
try {
// create a default kernel if necessary
if (kernel == null) {
kernel = KernelFactory.newInstance().createKernel(DEFAULT_KERNEL_NAME);
}
// boot the kernel
try {
kernel.boot();
} catch (Exception e) {
throw new FatalStartupError("Unable to boot the kernel", e);
}
// add our shutdown hook
kernel.registerShutdownHook(new Runnable() {
public void run() {
// bind the bootstrap services
for (Iterator iterator = services.keySet().iterator(); iterator.hasNext();) {
String name = (String) iterator.next();
try {
ObjectName objectName = new ObjectName(name);
kernel.stopService(objectName);
kernel.unloadService(objectName);
} catch (Exception e) {
// igore -- a real exception will be logged by the kernel
}
}
}
});
boolean failed = false;
try {
// bind the bootstrap services
for (Iterator iterator = services.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
String name = (String) entry.getKey();
Object service = entry.getValue();
try {
ObjectName objectName = new ObjectName(name);
kernel.loadService(objectName, new SimpleServiceFactory(service), classLoader);
kernel.startService(objectName);
} catch (Exception e) {
throw new FatalStartupError("Unable to bind bootstrap service '" + name + "' into the kernel", e);
}
}
// verify that all bootstrap services started successfully
LoaderUtil.verifyAllServicesRunning(kernel);
// load each location and verify that all services started successfully
for (Iterator iterator = locations.iterator(); iterator.hasNext();) {
String location = (String) iterator.next();
LoaderUtil.load(kernel, location);
LoaderUtil.verifyAllServicesRunning(kernel);
}
// if we have a child main class call it
if (next != null) {
next.main(args);
}
// if we are a daemon we wait here until the server stops
if (daemon) {
// add our shutdown hook
Runtime.getRuntime().addShutdownHook(new Thread("Shutdown Thread") {
public void run() {
kernel.shutdown();
}
});
while (kernel.isRunning()) {
try {
// wait for the kernel to be ready to exit
synchronized (kernel) {
kernel.wait();
}
} catch (InterruptedException e) {
// ignore - we check the variable above
}
}
}
} catch (RuntimeException e) {
failed = true;
throw e;
} catch (Error e) {
failed = true;
throw e;
} finally {
try {
kernel.shutdown();
} catch (Exception e) {
// if we are not alredy throwing an exception, throw a new exception
if (!failed) {
throw new FatalStartupError("Exception while shutting down kernel", e);
}
}
}
} finally {
Thread.currentThread().setContextClassLoader(oldClassLoader);
}
}
}