I'm using play framework 2.8.x
and I need to inject my config class to another class and I have written my custom module for creating config. My module looks like the following:
public class ConfigModule extends AbstractModule {
private Config config;
public ConfigModule(Environment environment, Config config) {
this.config = config;
}
@Override
protected void configure() {
bindRedisConfig();
}
void bindRedisConfig() {
System.out.println("LOAD");
RedisConfig redisConfig = new RedisConfig(
config.getString("configuration.redis.host")
, config.getInt("configuration.redis.port")
, config.getString("configuration.redis.password")
, config.getString("configuration.redis.domain")
);
bind(RedisConfig.class).annotatedWith(Names.named(Constant.CONFIG_REDIS)).toInstance(redisConfig);
}
}
and I try to inject it like this:
public class ProcessDataStore {
private final JedisPool jedisPool;
private final RedisConfig config;
@Inject
public ProcessDataStore(RedisConfig config) {
this.config = config;
}
}
my config class is very simple:
@Singleton
public class RedisConfig {
public final String host;
public final int port;
public final String password;
public final String domain;
public RedisConfig(String host, int port, String password, String domain) {
this.host = host;
this.port = port;
this.password = password;
this.domain = domain;
}
}
but when I run my application I get an exception:
1) Could not find a suitable constructor in config.RedisConfig. Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private.
at config.RedisConfig.class(RedisConfig.java:17)
while locating config.RedisConfig
for the 1st parameter of repository.ProcessDataStore.<init>(ProcessDataStore.java:25)
while locating repository.ProcessDataStore
for field at controllers.DashboardController.db(DashboardController.java:19)
while locating controllers.DashboardController
for the 5th parameter of router.Routes.<init>(Routes.scala:38)
at play.api.inject.RoutesProvider$.bindingsFromConfiguration(BuiltinModule.scala:137):
Binding(class router.Routes to self) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$4)
if I create default constructor without params my application not thrown any exception but injected RedisConfig
is empty.
I load my module to the my app:
play.modules.enabled += "modules.ConfigModule"
what can I do wrong?
I see 2 suspicious things.
1) @Singleton
annotation on RedisConfig
class. It can make injector to create and inject new instance of RedisConfig
class instead of redisConfig
.
2) Binding definition contains .annotatedWith(Names.named(Constant.CONFIG_REDIS))
. Therefore parameter of contructor of ProcessDataStore
shoudl be annotated with @Named
:
@Inject
public ProcessDataStore( @Named(Constant.CONFIG_REDIS) RedisConfig config) {...}