2
votes

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?

2

2 Answers

0
votes

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.

0
votes

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.