Переход на CDI 1.2 WELD Exception - PullRequest
0 голосов
/ 28 июня 2018

После перехода на CDI 1.2 в Liberty мое приложение начало выдавать WELD-исключение, которое мне неясно решить:

org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001334: Unsatisfied dependencies for type DataHandler with qualifiers @Any @DataHandlerBean WELD-001475: The following beans match by type, but none have matching qualifiers:
  - Session bean [class com.ibm.blueargus.feed.PathSquadHandler with qualifiers [@DataHandlerBean @Any]; local interfaces are [DataHandler],
  - Session bean [class com.ibm.blueargus.feed.DownAccessPointDataHandler with qualifiers [@DataHandlerBean @Named @Any]; local interfaces are [DataHandler],
  - Session bean [class com.ibm.blueargus.feed.ATTTicketDataHandler with qualifiers [@DataHandlerBean @Any]; local interfaces are [DataHandler],
  - Session bean [class com.ibm.blueargus.feed.WirelessClientDataHandler with qualifiers [@Named @DataHandlerBean @Any]; local interfaces are [DataHandler]

Это происходит, когда я выбираю компонент на основе значения пользовательской аннотации - требование приложения иметь возможность выполнять конкретную реализацию EJB на основе критериев, хранящихся в базе данных. Как мне обновить мой код для работы с CDI 1.1 и по-прежнему обеспечивать динамический выбор реализации EJB на основе пользовательского значения квалификатора? Есть ли лучший подход, который дал бы мне такую ​​же общую особенность?

Спецификация квалификации

@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface DataHandlerBean {

   String value();

}

Реализация аннотации:

public class DataHandlerBeanQualifier extends AnnotationLiteral <DataHandlerBean> implements DataHandlerBean {

    private String value;

    public DataHandlerBeanQualifier (String value) {
        this.value=value;
    }

    @Override
    public String value() {
        return this.value;
    }

}

Интерфейс EJB:

@Local
public interface DataHandler {

    public void extractData (Monitor monitor, DataFeed dataFeed) throws Exception;

}

Пример реализации EJB:

@Stateless
@DataHandlerBean("downAccessPointHandler")
public class DownAccessPointDataHandler implements DataHandler {

EJB Business Logic, вызывающая проблему (фрагмент): Значение в monitor.getDataHandler () используется для выбора соответствующей реализации EJB для передачи управления для дальнейшей обработки.

@Stateless
public class DataScannerImpl implements DataScanner {

    public static Logger logger = Logger.getLogger(DataScanner.class.getName());

    @Inject
    @Any
    private Instance <DataHandler> dataHandlerInstance;

    private String processMonitorList(List <Monitor> monitorList, boolean forceLoad) {
        ...

        try {
            dataHandler = dataHandlerInstance.select(new DataHandlerBeanQualifier(monitor.getDataHandler())).get();
            dataHandler.extractData(monitor, dataFeed);
            monitor.setDataFeed(dataFeed);
        } catch ( Exception e ) {
            e.printStackTrace();
            logger.warn("Could not execute dataHandler: " + monitor.getDataHandler(), e);
        }

        ...
    }
}

Все это работало нормально в моей предыдущей производственной среде на WebSphere v8.5. Веб-приложение использовало CDI 1.0.

Текущая среда (server.xml):

<featureManager>
    <feature>javaee-7.0</feature>
    <feature>webProfile-7.0</feature>
    <feature>ejbPersistentTimer-3.2</feature>
    <feature>ldapRegistry-3.0</feature>
    <feature>appSecurity-2.0</feature>
    <feature>localConnector-1.0</feature>
    <feature>jaxrs-2.0</feature>
    <feature>jaxrsClient-2.0</feature>
    <feature>servlet-3.1</feature>
    <feature>jpa-2.1</feature>
</featureManager>

Ответы [ 2 ]

0 голосов
/ 11 июля 2018

Проблема была вызвана опечаткой в ​​значениях базы данных, из-за которых значения monitor.getDataHandler() возвращали имена бинов, которые на самом деле не существовали.

0 голосов
/ 03 июля 2018

У вас должен быть метод @Producer, который будет внедрен в 4 класса, реализующих интерфейс DataScanner
4 класса должны быть аннотированы 4 различными аннотациями
Основываясь на вашей бизнес-логике, производитель выберет и "произведет" правильную реализацию
Затем вы можете сразу же ввести "DataScanner" туда, где вам это нужно:

@Inject
private DataHandler dataHandlerInstance;

Это описано в документации Сварка здесь

В документе производитель выбирает 2 варианта реализации интерфейса "PaymentProcessor": "@Synchronous PaymentProcessor syncPaymentProcessor" и "@Asynchronous PaymentProcessor asyncPaymentProcessor"

...