Has rawType handling changed between CDI 1.0/1.2?
starksm64 Oct 5, 2015 8:16 PMSo I'm reviving an old CDI 1.0 based application that I was running using weld and javase, and I'm seeing differences with how producer method are being matched up. The one case that no longer works involves a producer method like:
@Produced
@Produces
public static IStrategyStateMachineFactory getStrategySM(InjectionPoint ip, BeanManager beanManager) {
...
}
with an injection point like:
@Named("ParameterizedSTPCOStrategy")
public class ParameterizedSTPCOStrategy<S extends Enum, T extends Enum> extends NamedStrategy {
@Inject
@Produced
private IStrategyStateMachineFactory<S, T, IStrategyStateHandler<S, T>> factory;
...
and the IStrategyStateMachineFactory interface is:
public interface IStrategyStateMachineFactory<S extends Enum, T extends Enum, H> {
...
}
While this worked with CDI 1.0, this now fails with an unsatisfied dependency:
Exception in thread "main" org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type IStrategyStateMachineFactory<S, T, IStrategyStateHandler<S, T>> with qualifiers @Produced
at injection point [BackedAnnotatedField] @Inject @Produced private com.si.strategy.ParameterizedSTPCOStrategy.factory
at com.si.trading.strategy.ParameterizedSTPCOStrategy.factory(ParameterizedSTPCOStrategy.java:0)
...
Ok, so I changed the producer method to use a generic method:
public static <S extends Enum, T extends Enum> IStrategyStateMachineFactory<S, T, IStrategyStateHandler<S, T>> getStrategySM(InjectionPoint ip, BeanManager beanManager) {
...
and while this now does match the injection point, the code in the getStrategySM method to find beans that support the IStrategyStateMachineFactory rawType no longer matches. This code block does not produce anything because the call to the beanManager.getBeans(...) with the IStrategyStateMachineFactory rawType does not match any of the beans which implement the IStrategyStateMachineFactory interface:
// Look through the IStrategyStateMachineFactory beans
Set<Bean<?>> beans = beanManager.getBeans(IStrategyStateMachineFactory.class);
Bean<IStrategyStateMachineFactory> smfactoryBean = null;
for (Bean bean : beans) {
Named named = getName(bean.getQualifiers());
if (named != null) {
if (named.value().equals(name)) {
smfactoryBean = bean;
break;
}
}
}
When I dug into the weld 2.3.0.Final code, it does seem as though the type closure of the managed beans includes the implemented interface, but I can't tell how exactly the beanManager.getBeans(...) call is searching the beans.
So, all this is to ask:
1. should the original CDI 1.0 usage still be working under 1.2?
2. is there a simple change to get the beanManager.getBeans(...) call to return all of the managed beans that implement the IStrategyStateMachineFactory rawType? Note that I have hacked a workaround where I myself make a set of the beans implementing IStrategyStateMachineFactory in a weld Extension via the <T> void processBean(@Observes ProcessBean<T> bean) callback, and I use that set of beans rather than calling the bean manager.
If this should be working, I can try to come up with a simple example that show the usage and create a jira issue.
-
cdi-ex.zip 9.4 KB