Производитель CDI не признан в квалификаторах
У меня есть приложение 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]
После этого я попытался сделать следующее, чтобы устранить неоднозначные зависимости.
- /questions/1908678/cdi-neodnoznachnaya-zavisimost-ot-produces-pochemu/1908687#1908687 (Добавить классификатор)
- /questions/1908678/cdi-neodnoznachnaya-zavisimost-ot-produces-pochemu/1908688#1908688 (использовать @Any
)
- /questions/8212504/ispolzovanie-proizvoditelya-cdi-vyizyivaet-isklyuchenie-neodnoznachnyih-zavisimostej/8212514#8212514 (Использовать @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 ответ
Скорее всего, вы наблюдаете ограничение видимости спецификации Java EE. Существуют ограничения на то, что определенные архивы (EAR/lib, EJB jar, WAR) в EAR могут видеть и получать к ним доступ. Затем CDI следует той же схеме с инъекцией.
Реализация этих правил может очень незначительно отличаться в зависимости от того, как серверы приложений интерпретируют спецификацию. Теперь, если вам не хочется читать спецификацию (кто это делает?), То вы можете посмотреть на этот SO-ответ, который суммирует его, хотя и не исчерпывающе.
А именно, в вашем случае файл WAR может получить доступ к содержимому EJB, но не наоборот. В терминах CDI это означает, что EJB-jar не "видит" метод продюсера, который у вас там есть.
Что касается неоднозначного исключения зависимости, которое вы видели, когда делали ServiceConnector
боб - я не уверен на 100%, что это без репродуктора и некоторой отладки. Это может быть ошибка в том, как проверка выполняется в EAR, или это может быть предназначено, потому что теоретически из WAR-архива вы можете увидеть два bean-типа ServiceConnector
,
Что касается того, как обойти это - я могу думать только о расширениях CDI, которые (в интерпретации Weld) охватывают весь EAR. Поэтому использование расширения CDI для регистрации компонента может работать для вас независимо от того, какой архив это делает. Если вы идете по этому пути, посмотрите на AfterBeanDiscovery
Наблюдатель и зарегистрировать боб там.