How is the method run(T var1, Environment var2) in Application class called in Dropwizard?

Viewed 30

Within a Dropwizard application, the abstract run method in the Application class is usually overriden in the main service with something like this:

@Override
public void run(MyServiceConfiguration configuration, Environment environment) throws Exception {
    // application logic
}

I tried tracing the execution logic and couldn't figure out where/how that method is being called. Can someone point me in the right direction?

1 Answers

Let's start at the beginning, when you run your Dropwizard application as a server you're giving the server command on the command line interface (CLI). The example the documentation gives is:

java -jar target/hello-world-0.0.1-SNAPSHOT.jar server hello-world.yml

In io.dropwizard.Application (which you normally extend) we can see that the following commands are added to the bootstrap:

protected void addDefaultCommands(Bootstrap<T> bootstrap) {
    bootstrap.addCommand(new ServerCommand<>(this));
    bootstrap.addCommand(new CheckCommand<>(this));
}

In this case this is the instance of your class extending Application, which is given to the ServerCommand.

Then the run method in the same class will parse the CLI:

public void run(String... arguments) throws Exception {
    final Bootstrap<T> bootstrap = new Bootstrap<>(this);
    addDefaultCommands(bootstrap);
    initialize(bootstrap);
    // Should be called after initialize to give an opportunity to set a custom metric registry
    bootstrap.registerMetrics();

    final Cli cli = new Cli(new JarLocation(getClass()), bootstrap, System.out, System.err);
    // only exit if there's an error running the command
    cli.run(arguments).ifPresent(this::onFatalError);
}

When we follow cli.run(arguments).ifPresent(this::onFatalError); we end up in io.dropwizard.cli.Cli#run. In this method the command is parsed, and since we specified server it will find that command by name and execute it:

public Optional<Throwable> run(String... arguments) {
...
final Namespace namespace = parser.parseArgs(arguments);
final Command command = requireNonNull(commands.get(namespace.getString(COMMAND_NAME_ATTR)),
    "Command is not found");
try {
    command.run(bootstrap, namespace);
...

The server command will be an instance of io.dropwizard.cli.ServerCommand, which extends io.dropwizard.cli.EnvironmentCommand.

And it is in the EnvironmentCommand that we can see that your requested Application.run(...) method is executed:

protected void run(Bootstrap<T> bootstrap, Namespace namespace, T configuration) throws Exception {
    ...

    bootstrap.run(configuration, environment);
    application.run(configuration, environment);
    run(environment, namespace, configuration);
}

This line specifically:

application.run(configuration, environment);

The T configuration is added via the base class of EnvironmentCommand, which is io.dropwizard.cli.ConfiguredCommand.

All code is taken from Dropwizard version 2.1.0

Related