Recently I came across a corner cases regarding injection of Event and Instance with wildcards in them.
So cases such as:
@Inject
Event<?> wildEvent;
@Inject
Event<? extends Foo> extendsFooEvent;
@Inject
Instance<?> wildInstance;
I think the specification is currently not clear on whether this should work and I propose that we explicitly forbid it. Note that this includes:
- Validating the IPs like I showed in the code above
- As well as runtime validation for cases such as
BeanManager.createInstance().select(new TypeLiteral<Event<?>>(){}
- This should be doable as you can only get to wildcards using the
select(TypeLiteral, Annotation...) variant
Looking at existing implementations, I found that:
- Weld already forbids this for
Instance and Event (throwing a DefinitionException)
- Quarkus (Arc) forbids this for
Instance (DefinitionException) but permits Event
I think we should forbid it because of several reasons.
Firstly, in case of Instance, the specification IMO already indirectly suggests it is not permitted via required type of Instance combined with Legal injection point types combined with Legal bean types . Granted, this does not forbid it, but certainly doesn't list wildcard as allowed "type". Note that this does not apply to Event.
Secondly, usability - just having a wildcard (wildEvent field in the code above) or one with upper bound (extendsFooEvent in the code above) has basically no use. You cannot fire an actual type (i.e. String) event from it and attempting to select() a subclass won't compile either. For Event, the only "usable" case would be a wildcard with lower bound but even then it has dubious benefits as you might well have event with given actual type. The wildcard will also not help in infering any type variables found in the actual runtime payload type.
Similar applies to Instance where looking for a bean with wildcard type (which isn't allowed) doesn't make sense.
Thirdly, the type variable T of Event<T> and Instance<T> should represent a selected/required type and you normally cannot declare a type that would be a wildcard so you shouldn't be able to do it this way either.
Thoughts?
Cc @ljnelson whose question got me digging into this.
Recently I came across a corner cases regarding injection of
EventandInstancewith wildcards in them.So cases such as:
I think the specification is currently not clear on whether this should work and I propose that we explicitly forbid it. Note that this includes:
BeanManager.createInstance().select(new TypeLiteral<Event<?>>(){}select(TypeLiteral, Annotation...)variantLooking at existing implementations, I found that:
InstanceandEvent(throwing aDefinitionException)Instance(DefinitionException) but permitsEventI think we should forbid it because of several reasons.
Firstly, in case of
Instance, the specification IMO already indirectly suggests it is not permitted via required type ofInstancecombined with Legal injection point types combined with Legal bean types . Granted, this does not forbid it, but certainly doesn't list wildcard as allowed "type". Note that this does not apply toEvent.Secondly, usability - just having a wildcard (
wildEventfield in the code above) or one with upper bound (extendsFooEventin the code above) has basically no use. You cannot fire an actual type (i.e.String) event from it and attempting toselect()a subclass won't compile either. ForEvent, the only "usable" case would be a wildcard with lower bound but even then it has dubious benefits as you might well have event with given actual type. The wildcard will also not help in infering any type variables found in the actual runtime payload type.Similar applies to
Instancewhere looking for a bean with wildcard type (which isn't allowed) doesn't make sense.Thirdly, the type variable
TofEvent<T>andInstance<T>should represent a selected/required type and you normally cannot declare a type that would be a wildcard so you shouldn't be able to do it this way either.Thoughts?
Cc @ljnelson whose question got me digging into this.