Updating Dropwizard config at runtime

Yes. It is possible to reload the service classes at runtime.

Dropwizard by itself does not have the way to reload the app, but jersey has.

Jersey uses a container object internally to maintain the running application. Dropwizard uses the ServletContainer class of Jersey to run the application.

How to reload the app without restarting it -

  1. Get a handle to the container used internally by jersey

    You can do this by registering a AbstractContainerLifeCycleListener in Dropwizard Environment before starting the app. and implement its onStartup method as below -

In your main method where you start the app -

//getting the container instance
        environment.jersey().register(new AbstractContainerLifecycleListener()  {
        @Override
        public void onStartup(Container container) {
            //initializing container - which will be used to reload the app
            _container = container;
        }

    });  
  1. Add a method to your app to reload the app. It will take in the list of string which are the names of the service classes you want to reload. This method will call the reload method of the container with the new custom DropWizardConfiguration instance.

In your Application class

 public static synchronized void reloadApp(List<String> reloadClasses) {
        DropwizardResourceConfig dropwizardResourceConfig = new DropwizardResourceConfig();

        for (String className : reloadClasses) {
           try {
                Class<?> serviceClass = Class.forName(className);
                dropwizardResourceConfig.registerClasses(serviceClass);
                System.out.printf(" + loaded class %s.\n", className);
            } catch (ClassNotFoundException ex) {
                System.out.printf(" ! class %s not found.\n", className);
            }
        }
        _container.reload(dropwizardResourceConfig);

    }  

For more details see the example documentation of jersey - jersey example for reload

Consider going through the code and documentation of following files in Dropwizard/Jersey for a better understanding -

Container.java

ContainerLifeCycleListener.java

ServletContainer.java

AbstractContainerLifeCycleListener.java

DropWizardResourceConfig.java

ResourceConfig.java


No.

Yaml file is parsed at startup and given to the application as Configuration object once and for all. I believe you can change the file after that but it wouldn't affect your application until you restart it.

Possible follow up question: Can one restart the service programmatically?

AFAIK, no. I've researched and read the code somewhat for that but couldn't find a way to do that yet. If there is, I'd love to hear that :).


I made a task that reloads the main yaml file (it would be useful if something in the file changes). However, it is not reloading the environment. After researching this, Dropwizard uses a lot of final variables and it's quite hard to reload these on the go, without restarting the app.

class ReloadYAMLTask extends Task {
    private String yamlFileName;

    ReloadYAMLTask(String yamlFileName) {
        super("reloadYaml");
        this.yamlFileName = yamlFileName;
    }
 @Override
    public void execute(ImmutableMultimap<String, String> parameters, PrintWriter output) throws Exception {
        if (yamlFileName != null) {
            ConfigurationFactoryFactory configurationFactoryFactory = new DefaultConfigurationFactoryFactory<ReportingServiceConfiguration>();
            ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
            Validator validator = validatorFactory.getValidator();
            ObjectMapper objectMapper = Jackson.newObjectMapper();
            final ConfigurationFactory<ServiceConfiguration> configurationFactory = configurationFactoryFactory.create(ServiceConfiguration.class, validator, objectMapper, "dw");
            File confFile = new File(yamlFileName);
            configurationFactory.build(new File(confFile.toURI()));
        }
    }
}