I have two classes that implement an interface. The one is annotated as @Default
and @Named
. The other is annotated as @Alternative
@Default
@Named
public class ListService implements IListService {
@Override
public void doSomething()
print("default");
}
}
@Alternative
public class ListServiceMock extends BaseServiceMock implements IListService {
@Override
public void doSomething()
print("mock");
}
}
The injection happens like this:
public class SomeNavigator extends AbstractNavigator {
private IListService listService;
@Inject
public SomeNavigator(IListService listService) {
this.listService = listService;
}
public void doNavigate() {
this.listService.doSomething(); // Always prints "mock"
}
}
My beans.xml
file is in /src/main/webapp/WEB-INF/beans.xml and the project is built and packaged by Maven as a war file and deployed to JBoss EAP 6.3.3.GA (in a Docker container)
I believe that the alternative bean ListServiceMock
will only be injected if I include it in the beans.xml
file like this:
<?xml version="1.0"?>
<beans bean-discovery-mode="all" version="1.1"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:weld="http://jboss.org/schema/weld/beans"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd">
<alternatives>
<class>service.alternative.ListServiceMock</class>
</alternatives>
</beans>
However regardless of if that section is in the beans.xml
or not the alternative bean is always used.
Is there a reason why it seems the beans.xml
file is ignored in this case and the alternative bean is always selected for injection?
Appears to be related to the XML namespaces in the beans.xml
file. I swthced to these namespaces and it's working now.
<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">