Is it possible that ProcessBean<X> is not fired right for producer methods?
ljnelson Feb 2, 2018 5:45 PMBefore I file a bug, I wanted to make sure I'm not misreading anything.
My understanding is that it is fine to observe a ProcessBean event in an extension. Your observer method will be called when every bean—including producer methods, fields, etc.—is found.
The specification says that a ProcessProducerMethod event will be fired in case a producer method has been discovered. But an observer of just plain ProcessBean will still get notified. This all works in a case like this:
private final void processBean(@Observes final ProcessBean<?> event) { // note the wildcard
// do something with every managed bean, producer method, producer field, etc.
}
However, this does not seem to behave in the same way when we're talking about producer methods and their return types. Specifically, although the above works with an unbounded wildcard, if instead of a wildcard we specify a type, some interesting things happen. Let's do this:
// Hey, CDI, please watch for beans, including producer methods, that have a bean type of THE_RETURN_TYPE_OF_THE_PRODUCER_METHOD
private final <THE_RETURN_TYPE_OF_THE_PRODUCER_METHOD> void processBean(@Observes final ProcessBean<THE_RETURN_TYPE_OF_THE_PRODUCER_METHOD> event) {
// never called for any producer method returning THE_RETURN_TYPE_OF_THE_PRODUCER_METHOD!
}
Instead, what we see is:
private final <THE_TYPE_OF_THE_BEAN_HOUSING_THE_PRODUCER_METHOD> void processBean(@Observes final ProcessBean<THE_TYPE_OF_THE_BEAN_HOUSING_THE_PRODUCER_METHOD> event) {
// called for (e.g. managed) beans of type THE_TYPE_OF_THE_BEAN_HOUSING_THE_PRODUCER_METHOD; not what we want
}
So if I have:
@ApplicationScoped
public final class Factory {
@Produces
public Widget widgetMaker() { /*...*/ }
}
then I'm saying:
private final void processEveryBean(@Observes final ProcessBean<?> event) // will see a bean containing the bean type Widget, will see Factory too
private final void <T extends Widget> processOnlyWidgets(@Observes final ProcessBean<T> event) // will never see a bean containing the bean type Widget; will never get called in fact
The specification says (in ProcessBean's javadoc):
The event object type depends upon what kind of bean was discovered: […]
- For a producer method with method return type X of a bean with bean class T, the container must raise an event of type
ProcessProducerMethod
.
So either:
(a) private final void processBean(@Observes final ProcessBean<?> event) shouldn't get called for producer method return types (but it is in fact called in these cases), or
(b) private final <X> void processBean(@Observes final ProcessBean<X> event) is not being called for producer method beans with X among their bean types, but should be
Have I misunderstood something, or is this a bug in Weld 3.0.2.Final?