После перехода на 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>