2015-10-23 1 views
3

У меня есть точка инъекции в одном из моих классовWeld Неоднозначность зависимость с @Alternative

@Inject 
private UsbServices usbServices; 

и класс Weld с @Produces методом

public class AppProducer 
{ 

    @Produces 
    @Singleton 
    public UsbServices getUsbServices() 
    { 
     UsbServices usbServices = null; 
     try 
     { 
      usbServices = UsbHostManager.getUsbServices(); 
     } catch (SecurityException | UsbException e) 
     { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     return usbServices; 
    } 

} 

Я хотел бы поменять в альтернативной реализации в процессе интеграции , поэтому у меня есть альтернативный вариант вышеуказанного класса

@Alternative 
public class TestAppProducer 
{ 

    @Produces 
    @Singleton 
    public UsbServices getUsbServices() 
    { 
     return new UsbServicesSimulator(); 
    } 

} 

А также следующее в моем beans.xml внутри тестового пакета ресурсов/META-INF

<beans xmlns="http://java.sun.com/xml/ns/javaee" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
     http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> 
     <alternatives> 
      <class>xxx.TestAppProducer</class> 
     </alternatives> 
</beans> 

Чтобы проверить это, я пытаюсь пнуть Weld с его основным классом и вручную подключить USB-устройство «» , Метод испытания имеет следующий

Weld weld = new Weld(); 
WeldContainer container = weld.initialize(); 
PCSyncApplication app = container.instance().select(PCSyncApplication.class).get(); 
ServicesManager servMan = app.getServicesManager(); 
UsbServicesSimulator servSimulator = (UsbServicesSimulator) servMan.getUsbServices(); 
servSimualtor.attachDevice(new FakeDevice()); 

Но я получаю исключение, неоднозначное DEPENDENCY

Exception in thread "main" org.jboss.weld.exceptions.DeploymentException: Exception List with 2 exceptions: 
Exception 0 : 
org.jboss.weld.exceptions.DeploymentException: WELD-001409: Ambiguous dependencies for type UsbServices with qualifiers @Default 
    at injection point [BackedAnnotatedField] @Inject private xxx.manager.ServicesManager.usbServices 
    at xxx.manager.ServicesManager.usbServices(ServicesManager.java:0) 
    Possible dependencies: 
    - Managed Bean [class xxx.simulator.usb.UsbServicesSimulator] with qualifiers [@Any @Default], 
    - Producer Method [UsbServices] with qualifiers [@Any @Default] declared as [[BackedAnnotatedMethod] @Produces @Singleton public xxx.AppProducer.getUsbServices()] 

EDIT: Небольшое обновление, если я аннотировать UsbServicesSimulator следующим сообщение уходит,

@Alternative 
public class UsbServicesSimulator implements UsbServices 

Но я не совсем уверен, что понимаю почему. Я бы подумал, что TestAppProducer и <alternatives> раздел beans.xml будет достаточно?

+1

Фактически ваша ошибка указывает, что 'UsbServices' уже является управляемым компонентом. Вы должны «@ Veto», чтобы он не генерировал никаких определений бобов. –

+0

Реализация 'UsbServices', предоставляемая' UsbHostManager.getUsbServices() ', является сторонним классом, поэтому я не могу его аннотировать – PDStat

+0

С какими контейнерами (включая версию) вы работаете? –

ответ

0

С @ Альтернативной аннотацией вы можете отключить только тестовое обслуживание, но не разрешать неоднозначную зависимость. Если вы хотите включить альтернативу, основная версия не должна отображаться в пути класса или должна иметь более низкий приоритет, например, e.x. @Priority аннотируется или отключается с beans.xml или @Vetoed. Есть также некоторые другие методы,
вы можете найти полную документацию здесь https://docs.jboss.org/weld/reference/latest/en-US/html/injection.html#alternatives

Я предпочитаю использовать отдельные проекты или запустить тест с Arquillian и иметь в своем классе пути только тот класс, что мне нужно. Я бы не рекомендовал использовать приоритеты в этом случае. Потому что вам потребуется отключить или установить более низкий приоритет для вашей производственной версии.