问题
I have a problem with injecting an EJB into an abstract class which is the parent of my JSF CDI beans. In my project I am using MyFaces CODI 1.0.5 (ViewScope), Omnifaces 1.3, PrimeFaces 3.4.2 and GlassFish 3.1.2.
The application is an EAR, the abstract class is in an EJB module and the JSF CDI beans are in a WAR module:
webframework-demo.ear
|__ webframework-war.war -> concrete JSF CDI bean
|__ webframework-ejb-lib.jar -> abstract class with EJB injection
|__ lib\
|__ shared libs
My abstract class:
public abstract class AbstractListPageAction<T extends AbstractViewBean<K>, K extends Serializable> {
...
@EJB
private CriteriaFacadeLocal<K> facade;
@PostConstruct
public void create() {
...
facade.setEntityClass(getEntityClass());
...
}
...
public abstract Class<K> getEntityClass();
}
My CDI bean:
import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.ViewAccessScoped;
@Named
@ViewAccessScoped
public class UserListAction extends AbstractListPageAction<UserViewBean, UserEntity>
implements Serializable {
private static final long serialVersionUID = -1178878323047991855L;
...
@Override
public Class<UserEntity> getEntityClass() {
return UserEntity.class;
}
...
}
When I deploy the application and access a JSF page, UserListAction is created but CriteriaFacadeLocal is not injected and I end with a NullPointerException in the @PostConstruct method.
When I change UserListAction and add an empty @PostConstruct method then CriteriaFacade is injected and everything works fine:
@Named
@ViewAccessScoped
public class UserListAction extends AbstractListPageAction<UserViewBean, UserEntity>
implements Serializable {
private static final long serialVersionUID = -1178878323047991855L;
...
@PostConstruct
public void init() {
}
@Override
public Class<UserEntity> getEntityClass() {
return UserEntity.class;
}
...
}
I have beans.xml in every module. But why must I have an empty @PostConstruct method in my CDI bean? Is there a problem with an abstract class placed in a EJB module?
回答1:
Using generics with EJB can be somewhat problematic.
See Use of generics in EJB 3.1.
Or you can make a qualified
EJB in your hierarchy. See javax.inject.Qualifier.
回答2:
I Created answer from edited question:
I figured that it was probably a problem with the EAR/EAR modules classloaders. I moved webframework-ejb-lib.jar into the webframework-war.war WEB-INF/lib folder:
webframework-demo.ear
|__ webframework-war.war -> concrete JSF CDI bean
| |__ WEB-INF
| |__lib
| |__ webframework-ejb-lib.jar -> abstract class with EJB injection
|__ ... (other ejb modules)
|__ lib\
|__ shared libs
and suddenly everything is fine.
来源:https://stackoverflow.com/questions/15132673/how-inject-ejb-into-abstract-cdi-class