Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@Inject-ed value null in @FacesComponent

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 */
    }
}
like image 558
bobbel Avatar asked Oct 07 '13 11:10

bobbel


2 Answers

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:

  1. Handle CDI injection via lookup, or switch to EJB and do the simpler EJB lookup;
  2. 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?

like image 141
skuntsel Avatar answered Oct 13 '22 06:10

skuntsel


@FacesCompnent is managed by JSF and injection is not supported into them.

like image 43
rdcrng Avatar answered Oct 13 '22 07:10

rdcrng