[#4579] Invoke the subtype handler over a shadowed supertype handler#4733
Merged
smcvb merged 1 commit intoJul 13, 2026
Merged
Conversation
…ndler When a supertype and a subtype declare a message handler with the same signature, AnnotatedHandlerInspector#getUniqueHandlers kept the first member in HandlerComparator order. Its final tiebreaker is the Executable's generic string, which orders by declaring-class name, so a supertype whose name sorts first was selected. This is harmless for public or protected methods, since reflective invocation is virtually dispatched to the subtype, but private methods are bound statically, so the supertype's implementation was invoked instead of the subtype's. getUniqueHandlers now keeps, per method signature, the member declared by the most specific type. The subtype's handler wins, while an inherited handler that is not shadowed is still used. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Develop-KIM
requested review from
hatzlj,
laura-devriendt-lemon and
zambrovski
and removed request for
a team
July 9, 2026 18:59
Contributor
|
Thanks for picking this up, @Develop-KIM! I've just reviewed, approved, and merged your fix. Given that it points to |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue
Closes #4579.
Annotated message handling components could invoke a private handler declared in a supertype instead of the matching handler declared in the actual (inspected) type.
Root cause
AnnotatedHandlerInspector#getUniqueHandlersreturned, per method signature, the first member inHandlerComparatororder. The comparator's final tiebreaker isExecutable#toGenericString(), which orders by the declaring class name. When a supertype and the inspected subtype declare a handler with the same signature (same priority, payload type and parameters), the supertype was selected whenever its class name sorts first lexically.For public/protected methods this is invisible, because reflective invocation is virtually dispatched to the subtype's override. For private methods there is no virtual dispatch, so the supertype's implementation was actually executed.
Fix
getUniqueHandlersnow keeps, per method signature, the member declared by the most specific type. The subtype's own handler wins over a shadowed supertype handler, while an inherited handler that is not shadowed by the subtype is still used — so a private handler declared only in a base class keeps working for subtype instances.Tests
Added two behavioural tests to
AnnotatedEventHandlingComponentTest:@EventHandler→ the subtype's handler is invoked (fails before the fix);./mvnw -pl messaging,modelling testpasses.Note
This change was prepared with AI assistance; I have reviewed and verified the analysis, fix and tests locally.