I've got two demo projects with slightly different project structure. One produces a WAR archive and the other one produces an EAR archive.
In the WAR-project the injection of an @EJB
in the Backingbeans, @FacesConverter
and @FacesValidator
works as expected.
In the EAR-Project, the injection works only into the Backingbean, but not in @FacesConverter
or @FacesValidator
(although all three classes are in the same folder/jar). @PostConstruct
is also not working in @FacesConverter
and @FacesValidator
(but in BackingBean), so I'm definitely missing something important. But what?
I checked/copied web.xml
, faces-config.xml
and beans.xml
they are identical. beans.xml
is under WEB-INF
in the WAR-project and under META-INF
in the ejb-Module of the EAR-project.
The @FacesConverter
and @FacesValidator
are marked with managed=true
so CDI should work.
By default, I'm using Payara, but I tested it also on WildFly and the situation is the same (Mojarra 4.0.7).
I increased the log levels for some ...webcontainer.jsf...
classes, but I don't see any error or warning.
@FacesConverter(managed = true, value = "demoConverter")
public class DemoConverter implements Converter<DemoEntity>, Serializable {
...
@EJB
DemoRemote bean;
int i;
...
@PostConstruct
public void init() {i=42;}
@Override
public DemoEntity getAsObject(FacesContext facesContext, UIComponent uiComponent, String s) {
...
logger.info("[ (bean=" + bean + ") (i="+i+")] "); <-- bean always null and i=0!!!
...
}
...
}
CDI is not EAR-compatible. In case you have an EAR with multiple WARs, some CDI features would work in only one of these WARs.
Stick to WAR as long as you want to use CDI. In case you intend to share web artifacts (managed beans, faces converters, facelets templates, web resources, etc) among multiple WARs, put them in a so-called web fragment JAR file. Guidelines can be found in Structure for multiple JSF projects with shared code. Real world examples of these web fragment JAR files are OmniFaces and PrimeFaces.