• Launcher is essentially a highly abstracted and generalized implementation of main() methods, combined with DataKernel DI, and support of start/stop semantics.
  • It can be used in applications with pure DataKernel DI without the need of other DataKernel components.

To give you a better understanding of how Launchers work, let’s have a look at a simplified Launcher implementation in a nutshell:

public void launch(String[] args) throws Exception {"=== INJECTING DEPENDENCIES");
    Injector injector = createInjector(args);"EagerSingletons: " + injector.createEagerSingletons());
    Set<LauncherService> services = injector.getInstance(new Key<Set<LauncherService>>() {});
    Set<LauncherService> startedServices = new HashSet<>();"Post-inject instances: " + injector.postInjectInstances());"=== STARTING APPLICATION");"Starting LauncherServices: " + services);
    startServices(services, startedServices);
    onStartFuture.complete(null);"=== RUNNING APPLICATION");
    onRunFuture.complete(null);"=== STOPPING APPLICATION");

Step-by-step examination:

  • Create the Injector with Modules provided in Launcher
  • Inject top-level dependencies into the Launcher instance itself
  • Instantiate all keys marked as @EagerSingleton multibinder keygroup, exported by Launcher’s Modules
  • Start all services from Set<LauncherService> multibinder set, exported by Launcher’s Modules, and execute onStart() method
  • Execute run() method
  • After run() is finished (either due to finishing all app-specific computations or by responding to a shutdown request such as SIGKILL), execute onStop() method and stop all services

Here is an example of the Launcher lifecycle represented as logs (particularly, HttpServerLauncher which provides an AsyncHttpServer and an Eventloop for it) . So you can launch this example:

public final class HttpHelloWorldExample extends HttpServerLauncher {
	AsyncServlet servlet() {
		return request -> HttpResponse.ok200().withPlainText("Hello World");

	public static void main(String[] args) throws Exception {
		Launcher launcher = new HttpHelloWorldExample();

to see alike logs:

EagerSingletons: []
Post-inject instances: [HttpHelloWorldExample]

Starting LauncherServices: [io.datakernel.jmx.JmxModule, io.datakernel.service.ServiceGraphModule]
Starting LauncherService: io.datakernel.jmx.JmxModule
Starting LauncherService: io.datakernel.service.ServiceGraphModule
Creating ServiceGraph...
Starting services
Listening on [/]: AsyncHttpServer{listenAddresses=[/]}
Started io.datakernel.http.AsyncHttpServer

HTTP Server is listening on http://localhost:8080/
Stopping LauncherService: io.datakernel.jmx.JmxModule
Stopping LauncherService: io.datakernel.service.ServiceGraphModule
Stopping ServiceGraph...
Stopping services
  • Dependencies optionally required by Launcher from its Modules:
    • @EagerSingleton multibinder keygroup
    • Set<LauncherService> multibinder set

Dependencies exported by Launcher to its Modules:

class Launcher{
	public final Injector createInjector() {
	   return Injector.of(getInternalModule()
  private Module getInternalModule() {
     Class<Launcher> launcherClass = (Class<Launcher>) getClass();
     Key<CompletionStage<Void>> completionStageKey = new Key<CompletionStage<Void>>() {};

     return Module.create()


  // this method can be overridden by subclasses which extend Launcher,
  // provides business logic modules (for example, ConfigModule)
  protected Module getModule() {
      return Module.empty();
  // this method can be overridden by subclasses which extend Launcher,
  // overrides definitions in internal module
  protected Module getOverrideModule() {
      return Module.empty();
  • @Args String[] arguments of its Launcher.launch(String[] args) method, corresponding to main(String[] args) method
  • the Launcher instance itself
  • @OnStart CompletionStage<Void> future which is completed when application is wired and started
  • @OnRun CompletionStage<Void> future which is completed when is complete
  • @OnStop CompletionStage<Void> future which is completed when application is stopped

  • Launcher also has handy diagnostic and JMX properties:
    • Instant of launch, start, run, stop, and complete
    • Duration of start, run, stop, and total duration
    • Throwable applicationError property

More examples

Note: To run the examples, you need to clone DataKernel from GitHub:
$ git clone
And import it as a Maven project. Check out branch v3.0. Before running the examples, build the project.
The two following examples are located at datakernel -> examples -> core -> boot and datakernel -> examples -> core -> http respectively

Hello World Example

Here is a simple “Hello World” Launcher application:

public final class HelloWorldExample extends Launcher {
	String message;

	String message() {
		return "Hello, world!";

	protected void run() {

	public static void main(String[] args) throws Exception {
		Launcher launcher = new HelloWorldExample();

HTTP Server from scratch using Launcher

When creating HTTP servers or any other applications, you can either use some predefined solutions (see examples) or simple Launcher instead. In this case, you’ll need to take care of all of the needed dependencies and override some basic methods:

public final class CustomHttpServerExample extends Launcher {
	private static final int PORT = 8080;

	private AsyncHttpServer server;

	Eventloop eventloop() {
		return Eventloop.create();

	AsyncServlet servlet() {
		return request -> HttpResponse.ok200()
				.withPlainText("Hello from HTTP server");

	AsyncHttpServer server(Eventloop eventloop, AsyncServlet servlet) {
		return AsyncHttpServer.create(eventloop, servlet).withListenPort(PORT);

	protected Module getModule() {
		return ServiceGraphModule.create();

	protected void run() throws Exception {

	public static void main(String[] args) throws Exception {
		Launcher launcher = new CustomHttpServerExample();