You can now inject into JSF validators if you're using Java EE 8 and/or JSF 2.3.
Tested using Mojarra 2.3.9.payara-p2 on Payara Server 5.192 #badassfish.
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:body>
Hello from Facelets
<h:form>
<h:messages/>
<h:inputText value="#{someBean.txtField}" validator="someValidator"/>
</h:form>
</h:body>
</html>
import javax.inject.Named;
import javax.enterprise.context.Dependent;
@Named(value = "someBean")
@Dependent
public class SomeBean {
private String txtField;
public String getTxtField() {
return txtField;
}
public void setTxtField(String txtField) {
this.txtField = txtField;
}
}
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.FacesValidator;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
import javax.inject.Inject;
@FacesValidator(value = "someValidator", managed = true)
public class CustomValidator implements Validator<String> {
@Inject
NewClass newClass;
@Override
public void validate(FacesContext context, UIComponent component, String value)
throws ValidatorException {
System.out.println("validator running");
System.out.println("injected bean: " + newClass);
if (value != null && value.equals("badvalue")) {
throw new ValidatorException(new FacesMessage(newClass.getMessage()));
}
}
}
public class NewClass {
public String getMessage() {
return "secret message";
}
}
import javax.faces.annotation.FacesConfig;
// WITHOUT THIS INJECTION WILL NOT WORK!
@FacesConfig(version = FacesConfig.Version.JSF_2_3)
public class ConfigurationBean {
}
Should render something like:

I banged my head on the wall for about an hour before realizing the need for ConfigurationBean
. From the documentation:
FacesConfig.Version.JSF_2_3
This value indicates CDI should be used for EL resolution as well as enabling JSF CDI injection, as specified in Section 5.6.3 "CDI for EL Resolution" and Section 5.9 "CDI Integration"
And from this GitHub issue, https://github.com/eclipse-ee4j/glassfish/issues/22094:
By default, JSF 2.3 runs in a compatibility mode with previous releases of JSF, unless a CDI managed bean is included in the application with the annotation @javax.faces.annotation.FacesConfig. To switch into a JSF 2.3 mode you will need a configuration bean like below: (shows ConfigurationBean)
...
The fact that JSF needs to be switched into the "current version" was highly controversial. Pretty much the entire EG voted against that, but eventually we could not get around the backwards compatibility requirements that the JCP sets for Java EE and the spec lead enforces.