Reputation: 4197
I have a class which has two constructors. I am trying to create instances of this class using a guice factory. If no parameter is passed, then default constructor should be called. If a parameter is passed, then constructor with parameter should be called. But currently even if I pass a parameter to the factory method, still the default constructor is getting called. Constructor with parameter is not at all getting called. Below is my factory class.
public interface MapperFactory {
PigBagMapper createPigBagMapper(@Assisted("pigMetaInfoList") List<String> sourceMetaInfoList);
JsonMapper createJsonMapper(@Assisted("apiName") String apiName) throws EndpointNotFoundException, JsonMapperException;
JsonMapper createJsonMapper();
}
Below are the constructors I am trying to inject.
@AssistedInject
public JsonMapper() {
handlers = new LinkedList<>();
}
@AssistedInject
public JsonMapper(@Assisted("apiName") String apiName) throws EndpointNotFoundException, JsonMapperException {
somelogic();
}
Below is my module binding in Abstract Module implementing class.
install(new FactoryModuleBuilder()
.implement(PigBagMapper.class, PigBagMapperImpl.class)
.implement(JsonMapper.class, JsonMapperImpl.class)
.build(MapperFactory.class));
Below is how I am calling the constructor.
mapperFactory.createJsonMapper(apiName);
What am I doing wrong here? Any help would be much appreciated.
EDIT:
Please note that the JsonMapperImpl class has no constructor. It just has a public method and that's all.
Upvotes: 1
Views: 2770
Reputation: 12021
I see two issues.
Issue 1: You do not need to annotate the factory methods with @Assisted
Issue 2: Guice will try to create an isntance of JsonMapperImpl
when you use the factory. It will scan for proper JsonMapperImpl
contructors annotated with @AssistedInject
. There are none. You can't invoke new JsonMapperImpl("xyz")
, for example. This will be a compile time error, because The constructor JsonMapperImpl(String) is undefined.
You also do not have constructors annotated with @AssistedInject
in JsonMapperImpl
. It is empty.
If you rewrite your class in a similar way:
public class JsonMapperImpl extends JsonMapper
{
@AssistedInject
public JsonMapperImpl() {
super();
}
@AssistedInject
public JsonMapperImpl(@Assisted String apiName) {
super(apiName);
}
}
And:
public class JsonMapper
{
private String apiName;
public JsonMapper() {
}
public JsonMapper(String apiName) {
this.apiName = apiName;
}
public String getAPI(){return apiName;}
}
then JsonMapperImpl
will expose appropriate constructors and the code will work, e.g.:
JsonMapper noApi = factory.createJsonMapper();
JsonMapper api = factory.createJsonMapper("test");
System.out.println(noApi.getAPI());
System.out.println(api.getAPI());
Outputs:
null
test
Hope this helps.
Upvotes: 6