Производитель CDI не признан в квалификаторах - PullRequest
0 голосов
/ 26 февраля 2019

У меня есть приложение EAR с 2 модулями.Модуль WEB и EJB.

В модуле EJB есть несколько служб, которые внедряются в классы модуля WEB, что прекрасно работает.Но некоторые сервисы нуждаются в конфигурации на основе пользовательского контекста, который доступен только в WEB-модуле.Поэтому я попытался добавить производителя в модуль WEB.
Структура выглядит следующим образом:

app-ear
|
+- app-ejb
|   |
|   +- Service
|   +- ServiceConnector
|
+- app-web
    |
    +- ServiceConnectorProducer

Вот упрощенная версия этого кода:

Класс обслуживания, который получаетсоединитель введен в: (EJB)

public class Service {
    @Inject
    private ServiceConnector connector;
}

Класс соединителя, который будет обрабатывать соединение для службы: (EJB)

public class ServiceConnector {
    private final Config config;

    public ServiceConnector(final Config config) {
        this.config = config;
    }
}

Производитель для ServiceConnector: (WEB)

public class ServiceConnectorProducer {
    @Produces
    public ServiceConnector produce(UserContext userCtx) {
        // ... create config and set data from user context
        return new ServiceConnector(config);
    }
}

В этот момент производитель не распознается в точке внедрения, и я получаю неудовлетворенную ошибку зависимости:

org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type ServiceConnector with qualifiers @Default
  at injection point [BackedAnnotatedField] @Inject private Service.connector
  at Service.connector(Service.java:0)

Это происходит, даже если производитель был загружен контейнером:

WELD-000106: Bean: Producer Method [ServiceConenctor] with qualifiers [@Any @Default] declared as [[BackedAnnotatedMethod] @Produces public ServiceConenctorProducer.produce(UserContext)]

Когда я делаю ServiceConnector обнаруживаемым контейнером, добавляя конструктор по умолчанию, я, однако, получаю неоднозначную ошибку зависимостей:

Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001409: Ambiguous dependencies for type ServiceConnector with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject private Service.connector
at Service.connector(Service.java:0)
Possible dependencies: 
- Producer Method [ServiceConnector] with qualifiers [@Any @Default] declared as [[BackedAnnotatedMethod] @Produces public ServiceConnector.produce(UserContext)],
- Managed Bean [class ServiceConnector] with qualifiers [@Any @Default]

После этого я попытался выполнить следующие действия для разрешениянеоднозначные зависимости.
- https://stackoverflow.com/a/22985035 (Добавить классификатор)
- https://stackoverflow.com/a/36056972 (Использовать @Any)
- https://stackoverflow.com/a/29449040/11117616 (Использовать @Vetoed)

Но все эти решения приводят к неудовлетворенной ошибке зависимостиили.

WELD-001408: Unsatisfied dependencies for type ServiceConnector with qualifiers @SessionService
  at injection point [BackedAnnotatedField] @Inject @SessionService private Service.connector
  at Service.connector(Service.java:0)
WELD-001475: The following beans match by type, but none have matching qualifiers:
  - Managed Bean [class ServiceConnector] with qualifiers [@Any @Default]

Так что теперь у меня нет идей, как разрешить ситуацию.Как я могу получить ServiceConnector для производства в WEB-модуле?

1 Ответ

0 голосов
/ 28 февраля 2019

Скорее всего, вы наблюдаете ограничение видимости спецификации Java EE.Существуют ограничения на то, что определенные архивы (EAR / lib, EJB jar, WAR) в EAR могут видеть и получать к ним доступ.Затем CDI следует той же схеме с внедрением.

Реализация этих правил может очень незначительно отличаться в зависимости от того, как серверы приложений интерпретируют спецификацию.Теперь, если вам не хочется читать спецификацию (кто это делает, а?), То вы можете посмотреть на этот SO-ответ , который его суммирует, хотя и не исчерпывающе.

А именно, в вашем случае файл WAR может получить доступ к содержимому EJB, но не наоборот.В терминах CDI это означает, что EJB-jar не «видит» метод производителя, который у вас там есть.

Что касается исключения неоднозначной зависимости, которое вы видели, когда сделали ServiceConnector bean-компонентом - я не уверен на 100%что это без репродуктора и некоторой отладки.Это может быть ошибка в том, как проверка выполняется в EAR, или это может быть предназначено, потому что теоретически из архива WAR вы можете увидеть два bean-типа типа ServiceConnector.

Что касается того, как обойти это - одна вещь, которую я могупредставьте себе расширения CDI, которые (в интерпретации Weld) охватывают весь EAR.Поэтому использование расширения CDI для регистрации компонента может работать для вас независимо от того, какой архив это делает.Если вы пойдете этим путем, посмотрите на AfterBeanDiscovery наблюдатель и зарегистрируйте боб там.

...