5

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 */
    }
}
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
bobbel
  • 461
  • 6
  • 18

3 Answers3

14

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?

TownCube
  • 1,280
  • 1
  • 13
  • 32
skuntsel
  • 11,624
  • 11
  • 44
  • 67
  • 6
    Did you really test #2? UI component instance is created via JSF `Application#createComponent()`, not via CDI. So you basically need a custom `Application` implementation as well (exactly like OmniFaces has for those converters/validators). – BalusC Oct 07 '13 at 20:04
1

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

rdcrng
  • 3,415
  • 2
  • 18
  • 36
0

Passing the value in from the XHTML page via a composite component attribute worked for us.

TownCube
  • 1,280
  • 1
  • 13
  • 32