Неудовлетворенные зависимости, внедряющие @Stateless в управляемый компонент

Моя проблема отличается как от WELD-001408 Неудовлетворенные зависимости при внедрении EntityManager, так и WELD-001408 Неудовлетворенные зависимости. В то время как эти проблемы связаны с попыткой внедрить управляемый компонент в EJB без сохранения состояния, я пытаюсь сделать обратное.

Я получаю «Неудовлетворенные зависимости» при попытке внедрить интерфейсный компонент @Stateless @Local в веб-управляемый компонент. Я создаю EAR с различными модулями EJB и веб-модулем, используя Glassfish 4 build 89 на JDK 8. Ниже приведены подробности ошибки и конфигурации проекта.

Во-первых, вот ошибка:

SEVERE:   Exception while loading the app
SEVERE:   Undeployment failed for context /platform-app
SEVERE:   Exception while loading the app : CDI deployment failure:WELD-001408 Unsatisfied dependencies for type [SessionSettingsBeanLocal] with qualifiers [@MyClient] at injection point [[BackedAnnotatedField] @Inject @MyClient private com.comp.jsf.dropdown.Settings.settingsBean]
org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [SessionSettingsBeanLocal] with qualifiers [@MyClient] at injection point [[BackedAnnotatedField] @Inject @MyClient private com.comp.jsf.dropdown.Settings.settingsBean]

Пользовательский квалификатор (в проекте библиотеки):

@Documented
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
public @interface MyClient

Интерфейс EJB (в проекте библиотеки):

@Local
public interface SessionSettingsBeanLocal

Внедрение EJB (в проекте модуля EJB):

@Stateless
@MyClient
public class SessionSettingsBean implements SessionSettingsBeanLocal

Управляемый компонент (в веб-проекте — используется для JSF):

@Named
@javax.faces.view.ViewScoped
public class Settings implements Serializable {
    @Inject
    @MyClient
    private SessionSettingsBeanLocal settingsBean;

Наконец, все мои файлы beans.xml (модули EJB, сеть) выглядят следующим образом. Библиотеки, содержащие интерфейс и квалификатор, не содержат beans.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
       bean-discovery-mode="annotated">
</beans>

Компонент @Stateless должен зарегистрироваться, но не найден.


person John Manko    schedule 16.07.2014    source источник
comment
Почему вы смешиваете пользовательские квалификаторы CDI и EJB?   -  person ra2085    schedule 17.07.2014
comment
У меня не было проблем с этим именно в GF 3.1. Я использую квалификаторы, потому что у меня есть несколько bean-компонентов, реализующих один и тот же интерфейс @Local.   -  person John Manko    schedule 17.07.2014
comment
Я не думаю, что это правильный путь. Вы должны использовать устранение неоднозначности EJB 3.0 по строке, а не квалификатор CDI.   -  person ra2085    schedule 17.07.2014
comment
посмотрите здесь: antoniogoncalves.org/2011/04/ 07/injection-with-cdi-part-i   -  person ra2085    schedule 17.07.2014
comment
и тут. Очень хорошие примеры устранения неоднозначности EJB 3.0: oracle.com/ техсеть/статьи/java/   -  person ra2085    schedule 17.07.2014
comment
Кроме того, вы пытались использовать этот частный SessionSettingsBeanLocal sessionSettingsBean? (вместо только settingsBean, помните, что @Named является квалификатором по умолчанию)   -  person ra2085    schedule 17.07.2014
comment
Предоставленная вами ссылка Oracle рекомендует то, как я это делаю, а Адам Бьен приводит пример: квалификация зависимости с помощью строки небезопасна для типов... Спецификация CDI (JSR-299) не рекомендует использовать строковые разрешение зависимостей... Рекомендуемый способ уточнения и настройки зависимостей — использовать типизированные аннотации с необязательными атрибутами вместо простых строк. Эти аннотации называются квалификаторами. Это стандартная аннотация, помеченная аннотацией @Qualifier.   -  person John Manko    schedule 17.07.2014
comment
Ссылка не содержит пример вашей комбинации JSR-299/JSR-330. Он просто указывает на сходство между типами инъекций строк.   -  person ra2085    schedule 17.07.2014
comment
Адам Бьен приводит пример комбинации, вводя квалифицированные компоненты JSR-299 в компонент EJB (а не наоборот) ="nofollow noreferrer">adam-bien.com/roller/abien/entry/simplest_possible_ejb_3_15   -  person ra2085    schedule 17.07.2014
comment
Глядя на спецификацию 299, нашел пример для вашей комбинации, я обновлю ответ, который я опубликовал некоторое время назад. Дайте мне знать, как это происходит.   -  person ra2085    schedule 17.07.2014
comment
Спасибо ra2085. Я ценю это. Я разместил последующий комментарий ниже, который должен помочь. Я думаю, что проблема заключается в упаковке, но мне нужно выяснить, как упакованные в JAR компоненты @Named/scoped (предназначенные для использования WAR JSF) могут внедрить упакованные в EJB компоненты @Stateless.   -  person John Manko    schedule 18.07.2014


Ответы (3)


Попробуйте изменить режим bean-discovery с аннотированного на все

person Marina    schedule 26.07.2018
comment
подумайте о том, чтобы добавить больше деталей в свой ответ, чтобы его было легче понять другим людям. - person Inder; 26.07.2018

У вас в основном есть три варианта, как преодолеть это

Полный переход на CDI

Начиная с CDI 1.1 вы также можете использовать транзакции в своих bean-компонентах, поэтому, если вы не используете удаленные EJB, MDB или что-либо еще, специфичное для EJB, это будет правильным решением.

Создать EJB с квалификатором другим EJB

@Stateless
public class EJBProducer {

    @EJB
    private SessionSettingsBeanLocal settingsBean;

    @Produces 
    @MyClient
    public SessionSettingsBeanLocal getSettingsBean() {
        return settingsBean;
    }

}

Обратите внимание, что этот класс должен находиться в модуле WAR. Теперь вы можете внедрить этот EJB-компонент обычным образом в CDI-компоненты с помощью его квалификатора.

Распознавание компонентов EJB по имени JNDI

@Stateless
public class SessionSettingsBean implements SessionSettingsBeanLocal {}

Чем просто ввести его в класс, например

@EJB(name = "SessionSettingsBean") 
private SessionSettingsBeanLocal bean; 

Таким образом, вы можете вообще избежать CDI.

person Petr Mensik    schedule 17.07.2014
comment
Я не использую аннотацию инъекции @EJB. Я использую @Inject CDI, как рекомендуют многие разработчики EE. даже Гэвин Кинг: seamframework.org/107780.lace - person John Manko; 17.07.2014
comment
Конечно, я бы выбрал номер один или два на вашем месте, но я думаю, вы должны знать обо всех вариантах. - person Petr Mensik; 17.07.2014
comment
Ну, я думаю, это могла быть ошибка с моей стороны, но я не уверен, когда инъекция приемлема. Именованный bean-компонент (Settings), имеющий точку внедрения EJB (SessionSettingsBeanLocal), на самом деле находится в JAR-файле. Теперь эти @Named @javax.faces.view.ViewScoped bean-компоненты (т. е. управляемые bean-компоненты для JSF) могут быть внедрены как в WAR-, так и в JAR-бины, но EJB, зарегистрированные из EJB-пакета, не видны для JAR. Если я конвертирую пакет JAR в EJB, то мои EJB без сохранения состояния внедряются, но тогда внедрение @Named @javax.faces.view.ViewScoped bean-компонентов в другие bean-компоненты в том же пакете завершается неудачно. - person John Manko; 18.07.2014