Как внедрить EJB в абстрактный класс CDI?

У меня проблема с внедрением EJB в абстрактный класс, который является родительским для моих JSF-компонентов CDI. В своем проекте я использую MyFaces CODI 1.0.5 (ViewScope), Omnifaces 1.3, PrimeFaces 3.4.2 и GlassFish 3.1.2.

Приложение представляет собой EAR, абстрактный класс находится в модуле EJB, а компоненты JSF CDI находятся в модуле WAR:

webframework-demo.ear
|__ webframework-war.war -> concrete JSF CDI bean
|__ webframework-ejb-lib.jar -> abstract class with EJB injection
|__ lib\
    |__ shared libs

Мой абстрактный класс:

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();

}

Мой компонент CDI:

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;
    }

    ...
}

Когда я развертываю приложение и получаю доступ к странице JSF, создается UserListAction, но CriteriaFacadeLocal не вводится, и я заканчиваю NullPointerException в методе @PostConstruct.

Когда я меняю UserListAction и добавляю пустой метод @PostConstruct, тогда вводится CriteriaFacade, и все работает нормально:

@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;
    }

    ...
}

У меня есть beans.xml в каждом модуле. Но почему в моем компоненте CDI должен быть пустой метод @PostConstruct? Есть ли проблема с абстрактным классом, помещенным в модуль EJB?


person kralm    schedule 28.02.2013    source источник


Ответы (2)


Использование дженериков с EJB может быть несколько проблематичным.

См. Использование универсальных шаблонов в EJB 3.1.

Или вы можете создать qualified EJB в своей иерархии. См. javax.inject.Qualifier.

person Jin Kwon    schedule 28.02.2013
comment
Спасибо за ваш ответ. Я знаю, что дженерики могут быть проблематичными, но я нигде не нашел, что именно я могу и не могу. Я пришел к решению, посмотрите мой отредактированный вопрос. - person kralm; 04.03.2013

Я создал ответ на отредактированный вопрос:

Я подумал, что это, вероятно, проблема с загрузчиками классов модулей EAR / EAR. Я переместил webframework-ejb-lib.jar в папку webframework-war.war WEB-INF / lib:

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

и вдруг все нормально.

person Kukeltje    schedule 13.09.2018