Open buko opened 3 years ago
Thank you very much for the detailed report! I'll look it next week
I tried this on 3.0.3 and see no errors. Probably you are using not the latest version: could you please try 3.0.3.
Also, probably there is some misunderstanding:
an attempt is made to resolve against one of those sub-interfaces. ... GenericsResolver.resolve(Impl.class, FooParticipant.class).genericTypes()
This is not a resolution by the interface: it is a resolution of Impl
, ignoring sub-hierarchy starting with FooParticipant
.
For example, this is the resolution context of Impl alone: GenericsResolver.resolve(Impl.class)
class IgnoringFailTest.Impl<Object> <-- current
implements FooParticipant<Object>
extends Participant<Object>
implements BarParticipant<Object>
extends Participant<Object>
And this is your case: GenericsResolver.resolve(Impl.class, FooParticipant.class)
class IgnoringFailTest.Impl<Object> <-- current
implements BarParticipant<Object>
extends Participant<Object>
Ignored classes were introduced to speed up the resolution on very large hierarchies or to workaround some possible bugs.
Also, GenericsResolver.resolve(Impl.class, FooParticipant.class).genericTypes()
will show you generics of the Impl
class and not FooParticipant
.
When you need to resolve generics of some subtype in the hierarchy you first need to resolve complete hierarchy from the root class, navigate to target subtype and only then get generics:
GenericsContext.resolve(Impl.class).type(FooParticipant.class)
is (note "current" marker shifted)
class IgnoringFailTest.Impl<Object>
implements FooParticipant<Object> <-- current
extends Participant<Object>
implements BarParticipant<Object>
extends Participant<Object>
Now .genericTypes()
will return generics of FooPrticipant
.
Note: Hierarchies presented above are rendered with context.toString(): you can always look it in the debugger (or just log the entire context)
It seems like generics-resolver doesn't handle the case where a (generic) class implements multiple sub-interfaces and an attempt is made to resolve against one of those sub-interfaces. Given:
Then attempts to invoke to call
GenericsResolver.resolve(Impl.class, FooParticipant.class).genericTypes()
throws a very nasty exception stack trace[1].There are two problems here:
Note that the code above works fine if Impl implements only
FooParticipant
orBarParticipant
. The problem only occurs when Impl implements both.Workaround
A workaround to the issue is to resolve Impl.class against the base interface Participant.class. This produces the desired behavior and is equivalent because the same generic parameters must be passed to all the generic sub-interfaces interfaces. It seems like generics-resolver could do something similar, automatically: if a class implements multiple generic sub-interfaces of the same base generic-interface then attempts to resolve the implementation class against a generic sub-interface should be treated as an attempt to resolve against the base generic-interface.
[1]