I have the impression that CDI is not working with classes that have a @javax.faces.component.FacesComponent
. Is this true?
Here's my example, that doesn't work. The MyInjectableClass
is used at other points in the code where injection is not a problem, so it must be about the @FacesComponent
annotation I think.
The class I want to inject:
@Named
@Stateful
public class MyInjectableClass implements Serializable {
private static final long serialVersionUID = 4556482219775071397L;
}
The component which uses that class;
@FacesComponent(value = "mycomponents.mytag")
public class MyComponent extends UIComponentBase implements Serializable {
private static final long serialVersionUID = -5656806814384095309L;
@Inject
protected MyInjectableClass injectedInstance;
@Override
public void encodeBegin(FacesContext context) throws IOException {
/* injectedInstance is null here */
}
}
Unfortunately, even for JSF 2.2 @FacesComponent
, @FacesValidator
and @FacesConverter
are not valid injection targets (read What's new in JSF 2.2? by Arjan Tijms for more details). As Arjan points out:
It’s likely that those will be taken into consideration for JSF 2.3 though.
What can you do for now? Well, you've got basically two choices:
- Handle CDI injection via lookup, or switch to EJB and do the simpler EJB lookup;
- Annotate tour class with
@Named
instead of @FacesComponent
, @Inject
the component the way you did and register your component in faces-config.xml. As the UI component instance is created via JSF Application#createComponent(), not via CDI you will also need a custom Application implementation as well (exactly like OmniFaces has for those converters/validators).
And, by the way, you've got two issues with what you've got this far: (1) what is meant by @Named @Stateful
when the former is from a CDI world and the latter is from EJB world and (2) are you sure you intend to keep state in a faces component that's basically recreated on every request?
@FacesCompnent
is managed by JSF and injection is not supported into them.
Passing the value in from the XHTML page via a composite component attribute worked for us.