Weld на Java SE не использует альтернативу

Я имею projectA, projectB, а также projectC Затмение Maven проектов.

  • ProjectA содержит:
    • IMyApi интерфейс.
    • "Пустой" META-INF\beans.xml файл.
  • ProjectB содержит:
    • IMyConfig интерфейс.
    • MyConfigJndi реализация IMyConfig,
    • MyApiImpl реализация IMyApi, с собственностью @Inject private IMyConfig config;,
    • "Пустой" META-INF\beans.xml файл.
  • ProjectC содержит:
    • MyConfigAlter реализация IMyConfigпомечены как @Alternative,
    • Main класс (и метод), который инициализирует Weld SE и извлекает IMyApi боб.
    • META-INF\beans.xml где MyConfigAlter указан в alternatives раздел.

Теперь я бегу Main класс, а IMyApi боб успешно получен (как MyApiImpl пример). Но такой случай был, в его config собственность, введенная с MyConfigJndi экземпляр, вместо альтернативной версии (MyConfigAlter)

Я использую Eclipse Luna + M2Eclipse.

Что я делаю неправильно?

ОБНОВЛЕНИЕ: я узнал, что с помощью @Specializes вместо @Alternative решает проблему, но я все еще думаю, что это не правильное решение (в некоторых ситуациях у меня может не быть доступа к реализации по умолчанию).

ОБНОВЛЕНИЕ 2:

Я использую Weld-se, 2.2.10. Наконец:

<dependency>
    <groupId>org.jboss.weld.se</groupId>
    <artifactId>weld-se</artifactId>
    <version>2.2.10.Final</version>
    <scope>runtime</scope>
</dependency>

И инициализация просто

WeldContainer weld =
  new Weld().
    initialize();
IMyApi myApi =
  weld.
    instance().
    select(
      IMyApi.
        class).
    get();

2 ответа

Решение

Выбор альтернативы с помощью alternatives элемент в beans.xml дескриптор влияет только на соответствующий архив бина, т.е. ProjectC в вашем случае, как описано в разделе Объявление выбранных альтернатив для архива бинов. Исходя из этого, это логично, что ProjectB архив бобов получает MyConfigJndi реализация внедрена.

Начиная с CDI 1.2, можно глобально выбрать альтернативу для приложения, используя @Priority аннотация, как описано в разделе Объявление выбранных альтернатив для приложения.

Так что в вашем случае вы могли бы написать:

@Priority(Interceptor.Priority.Application)
@Alternative
class MyConfigAlter {
}

Еще один способ решить эту проблему - использовать -Dorg.jboss.weld.se.archive.isolation=false - из http://docs.jboss.org/weld/reference/2.2.11.Final/en-US/html/environments.html

Причина, по которой это происходит, заключается в том, что каждый JAR на пути к классам становится своим собственным архивом компонентов. Поскольку спецификация CDI с 1.2 не включает спецификацию SE, нет определения того, как classpath работает в этом режиме. Это не обязательно то, как будет разрабатываться приложение SE, поскольку у вас нет уникальных загрузчиков классов для каждого JAR-файла.

Другие вопросы по тегам