14

I wrote a converter. I am using CDI and injection parallel. In that case the classes are not injected. How can I make the injection possible?

@FacesConverter(forClass = MyClass.class)

public class MyConverter implements Converter{

    @EJB
    private ClassForEJB classForEJB;

    @Inject
    private ClassForInject classForInject;

// Converter Methods
}
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Kayser
  • 6,544
  • 19
  • 53
  • 86

1 Answers1

29

The @FacesConverter isn't an eligible injection target. Replace it by @ManagedBean or @Named. As you'd like to use CDI as as well, use @Named.

@Named
@ApplicationScoped // I assume that your converter doesn't have any state.
public class MyConverter implements Converter {
    // ...
}

You only need to change the way it's been referenced in the views. You cannot rely on forClass anymore. You'd need to explicitly specify it as #{myConverter}.

<h:inputSomething ... converter="#{myConverter}" />

or

<h:inputSomething ...>
    <f:converter binding="#{myConverter}" />
</h:inputSomething>

If you really need to keep the @FacesConverter in favor of forClass, then you'd need to grab the EJB manually by JNDI. A concrete example is shown in this blog article. I can however not tell that for CDI beans.

The JSF guys have confirmed this embarrassing oversight and they will make the @FacesConverter an eligible injection target in upcoming JSF 2.2, see also JSF spec issue 763 JSF 2.3.

See also:


Update if you happen to use JSF utility library OmniFaces, or are open to using it, since its version 1.6, when just having OmniFaces JAR in /WEB-INF/lib, all @FacesConverters (and @FacesValidators) in your webapp automatically become eligible for CDI and EJB injection without any extra effort.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Is it a problem to have a converter without Facesconverter annotation? For performance or something else? – Kayser Oct 31 '12 at 12:21
  • No. It just changes the way how it's been managed. – BalusC Oct 31 '12 at 12:22
  • 1
    It works as expected from BalusC – Kayser Oct 31 '12 at 13:04
  • Your answers always cleans and working. – ehsun7b Apr 17 '14 at 07:18
  • "*The JSF guys have confirmed this embarrassing oversight and they will make the `@FacesConverter` an eligible injection target **in upcoming JSF 2.2***" Why is this not a fact in JSF 2.2 yet (even in the latest version JSF 2.2.8-02)? – Tiny Oct 22 '14 at 15:31
  • 2
    @Tiny: it didn't made into JSF 2.2. They postponed it at the last moment to JSF 2.3 because it had an unexpected side effect which they couldn't fix in short time before official JSF 2.2 release. Again, OmniFaces to the rescue. – BalusC Oct 22 '14 at 16:15
  • @BalusC Dumb question : You said ApplicationScoped, so the instance will be shared through all users. Won't that bring problems like delays and such? I mean is it a risk that should be considered ? – Ced Sep 02 '15 at 03:01
  • @Ced: Java is multithreaded. – BalusC Sep 02 '15 at 06:13
  • Is there a difference between Omnifaces facesConverter and a `@Named` `@ApplicationScoped` annotated converter ? Dunno which one to pick. – Ced May 10 '16 at 21:42
  • @Ced: see duplicate for (dis)advantage. – BalusC May 11 '16 at 06:59
  • There is nothing there. I guess it's just about the same anyway. I was just interested to know if omnifaces made those RequestScoped or if they were created once and reused. Oh maybe you meant the forClass. – Ced May 11 '16 at 08:12
  • It seems that it is not supported in JSF 2.3, I get a NPE. :( – Hicham Sep 13 '19 at 14:36