I want to use Guava's Service Manager to manage services in my Dropwizard application.
ServiceManagerProvider
provides the service manager:
@Singleton
public class ServiceManagerProvider implements Provider<ServiceManager> {
@Inject
Set<Service> services;
public static Multibinder<Service> serviceRegistry(Binder binder) {
return Multibinder.newSetBinder(binder, Service.class);
}
@Override
public ServiceManager get() {
return new ServiceManager(services);
}
}
ManagedGuavaServices
is a Managed
object that interacts with the Service Manager to start/stop services:
public class ManagedGuavaServices implements Managed {
@Inject
private ServiceManager _serviceManager;
@Inject
public ManagedGuavaServices(ServiceManager serviceManager) {
_serviceManager = serviceManager;
}
@Override
public void start() throws Exception {
_serviceManager.startAsync();
}
@Override
public void stop() throws Exception {
_serviceManager.stopAsync();
}
}
MyModule
is the module where the Guice bindings are specified:
public class MyModule extends DropwizardAwareModule<MyConfig> {
...
@Override
protected void configure() {
bind(ServiceManager.class).toProvider(ServiceManagerProvider.class);
bind(Managed.class).to(ManagedGuavaServices.class).in(Singleton.class);
}
}
And MyApplication
is the Dropwizard application that depends on MyModule
:
public class MyApplication extends Application<MyConfig> {
@Inject
private Managed managedServices;
...
@Override
public void initialize(Bootstrap<MyConfig> bootstrap) {
bootstrap.addBundle(GuiceBundle.builder()
.printDiagnosticInfo()
.printGuiceBindings()
.enableAutoConfig(getClass().getPackage().getName())
.modules(
new MyModule()
)
.build());
}
...
@Override
public void run(MyConfig config, Environment environment) {
environment.lifecycle().manage(managedServices);
}
}
It seems like everything has been wired together, but when I run the application, I get the error message:
java.lang.NullPointerException
at java.base/java.util.Objects.requireNonNull(Objects.java:221)
at io.dropwizard.lifecycle.setup.LifecycleEnvironment.manage(LifecycleEnvironment.java:45)
at com.example.MyApplication.run(MyApplication.java:188)
at com.example.MyApplication.run(MyApplication.java:60)
at io.dropwizard.cli.EnvironmentCommand.run(EnvironmentCommand.java:44)
at io.dropwizard.cli.ConfiguredCommand.run(ConfiguredCommand.java:87)
at io.dropwizard.cli.Cli.run(Cli.java:78)
at io.dropwizard.Application.run(Application.java:94)
at com.example.MyApplication.main(MyApplication.java:70)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at com.webobjects._bootstrap.WOBootstrap.main(WOBootstrap.java:118)
which essentially means that the injected managedServices
in MZPaymentApplication
is null when the application is run.
What is wrong here? Is it the same problem as in this SO question? If so, where should the @PostConstruct
be?