Reputation: 6466
I have the following classes:
@Named
@ViewScoped
public class BaseClass {
private SomeDependency dep;
public BaseClass(){}
@Inject
public BaseClass(SomeDependency dep) {
this.dep = dep;
}
@PostConstruct
private void initialize() {
dep.doSomething(); // Point "A"
}
public String getProperty() {
return "BaseClass-Property";
}
@Specializes
public class SpecialClass extends BaseClass() {
@Override
public String getProperty() {
return "SpecialClass-Property";
}
}
Now in some .xhtml I have something like
<h:outputText value="#{baseClass.property}" />
This works fine without the SpecialClass
. It breaks with a NullPointerException
at Point "A" if I include the SpecialClass
in the project.
Well, according to the Weld specification, this is more or less intended behavior:
When an enabled bean specializes another bean, the other bean is never instantiated or called by the container.
Nevertheless, now I have to make sure that every @Specializes
bean implements the complete constructor like
public SpecialClass() {}
@Inject
public SpecialClass(SomeDependency dep) { super(dep); }
which IMHO is kind of counter-intuitive and produces a lot of duplicated, boilerplate code, especially with something like 5-6 arguments for every constructor. Also, this is never caught when creating a new specialized bean since the project is always still compile clean.
Am I doing something wrong or is there no alternative to implementing the constructors over and over again?
BTW, I do use Constructor Injection to create easily testable classes where I can just use the constructor to "Inject" dummy implementations of the dependencies.
Upvotes: 1
Views: 906
Reputation: 713
CDI 1.1 spec at section 4.3 says:
"The only way one bean can completely override a second bean at all injection points is if it implements all the bean types and declares all the qualifiers of the second bean."
Your base class is annotated with the Named qualifier and the specializing class is not. You should also mark it with Alternative and enable it in beans.xml. There's also the ViewScoped annotation. Unless it's the Omnifaces' ViewScoped, it looks like you're mixing up JSF managed beans with CDI beans.
Upvotes: 1