I have projectA
, projectB
, and projectC
Eclipse Maven projects.
ProjectA
contains:IMyApi
interface.- "Empty"
META-INF\beans.xml
file.
ProjectB
contains:IMyConfig
interface.MyConfigJndi
implementation ofIMyConfig
.MyApiImpl
implementation ofIMyApi
, with a property@Inject private IMyConfig config;
.- "Empty"
META-INF\beans.xml
file.
ProjectC
contains:- a
MyConfigAlter
implementation ofIMyConfig
, marked as@Alternative
. - a
Main
class (and method) that initializes Weld SE and retrieves aIMyApi
bean. - a
META-INF\beans.xml
whereMyConfigAlter
is listed in thealternatives
section.
- a
Now, I run the Main
class, and the IMyApi
bean is successfully retrieved (as a MyApiImpl
instance). But such an instance has been, in its config
property, injected with a MyConfigJndi
instance, instead of the alternative version (MyConfigAlter
)
I am using Eclipse Luna + M2Eclipse.
What am I doing wrong?
UPDATE: I found out that using @Specializes
instead of @Alternative
solves the issue, but I still think it is not the proper solution (in some situation I may not have access to the "default" implementation).
UPDATE 2:
I am using Weld-se, 2.2.10.Final:
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se</artifactId>
<version>2.2.10.Final</version>
<scope>runtime</scope>
</dependency>
And the initialization is simply
WeldContainer weld =
new Weld().
initialize();
IMyApi myApi =
weld.
instance().
select(
IMyApi.
class).
get();
Selecting an alternative using the
alternatives
element in thebeans.xml
descriptor only affects the corresponding bean archive, i.e.ProjectC
in your case, as documented in Declaring selected alternatives for a bean archive. Based on that, this is logical that theProjectB
bean archive gets theMyConfigJndi
implementation injected.Since CDI 1.2, it is possible to select an alternative globally for the application using the
@Priority
annotation as documented in Declaring selected alternatives for an application.So in your case, you could write: