Search code examples
javamicroservicesbackenddropwizard

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


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?


Solution

  • 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