Crusaderpyro Crusaderpyro - 4 months ago 25
Java Question

How to create instance of a class which is created using guice factory assisted inject and is extended from an abstract class?

I have the following hirarchy:

~interface Car

~ abstract class SportsCar

~ class Ferrari


I create an instance of class Ferrari using a FerrariFactory (code in module is shown below):

install(new FactoryModuleBuilder().build(FerrariFactory.class));


The FerrariFactory interface has the following method where I use assisted inject to inject parts (which is xml element contaiing all parts i.e. Ferrari specific parts + Sports car parts):

Ferrari create(@Assisted Element partsElement);


When I create a Ferrari instance, I am using the following:

ferrariFactory.create(partsElement);


The Ferrari constructor is called first:

@Inject
public Ferrari(Element parts) {
super(parts);
this.ferrariRadio= getElementValue(parts, "Parts/FerrariParts/ferrariRadio");
}


Since first line is a call for the superclass constructor of SportsCar:

public SportsCar (Element parts) {
super();
System.out.println("SportsCarconstructor: 1");
System.out.println("SportsCarconstructor: 2 "+parts);
...
... // where I set the basic parts from the parts xml element
}


Since the SportsCar is an abstract, I have no binding in the guice module. I am not sure how to bind it. Also, I get a NullPointerException at the second sysout line in the SportsCar constructor even though I am not accessing anything via null (weird case of null pointer).

Any suggestions on whether it is a binding problem or why my abstractclass constructor is unable to set parts ?

Answer

Ok. Found the answer. I had missed two things:

1. Missed the @Assisted annotation in the Ferrari constructor:

    @Inject
    public Ferrari(@Assisted Element parts) {
     super(parts);
....
    }

2. I can declare the abstract class and implementation in the module as follows:

install(new FactoryModuleBuilder().implement(SportsCar.class,Ferrari.class).build(FerrariFactory.class));