Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AbstractMethodError for default method on base class interface #461

Open
zznty opened this issue Dec 16, 2023 · 1 comment
Open

AbstractMethodError for default method on base class interface #461

zznty opened this issue Dec 16, 2023 · 1 comment

Comments

@zznty
Copy link

zznty commented Dec 16, 2023

Repro project:
IkvmIssueRepro.zip

Basically SlashCommandInteractionEvent internally holds instance of SlashCommandInteractionImpl which is subclass of CommandInteractionImpl that implements interface CommandInteractionPayloadMixin with default method body for getName()

But when i try to call getName() it throws java.lang.AbstractMethodError as ikvm has generated for it (see screenshot)
image

@wasabii
Copy link
Contributor

wasabii commented Jan 6, 2024

Having had a chance to look at this. Here's what I've found so far. It is probably a bug.

IKVM implements default interface methods as Miranda methods. That is, methods which are implicitely created on sub-types based on the declaration on the extended super type. We do this because historically .NET has not supported any notion of default interface methods. Core does now, but Framework still does not.

In this case, CommandInteractionPayload exposes the method getName() as an abstract. Because it is an interface with no default implementation. CommandInteractionPayloadMixin implements CommandInteractionPayload, and redeclares the method as an override with a default. Thus, anybody extending CommandInteractionPayloadMixin, should derive a miranda implementation from CommandInteractionPayloadMixin.

However, the interface SlashCommandInteraction implements CommandInteraction which implements CommandInteractionPayload. But does NOT implement CommandInteracationPayloadMixin.

So there are two paths to getName(). One through an interface tree, and the other through the implementation tree, where the implementation tree contains the default implementation, but the interface tree does not. I guess this is what they mean by a mixin: a set of default implementations for interfaces which can optionally be declared.

I'm going to have to sit down with the JVM spec for awhile and figure out what we're supposed to be doing here, and whether we're doing what we're supposed to be doing.

But what I think is happening is that when discovering the implemented methods, we go in order of implementation expressed by the class file metadata, which expresses the hierarchy. And since the Mixin appears later, at that time, we've already traversed an interface hierarchy where no default implementation existed. Essentially we're seeing getName on CommandInteractionPayload with no body before we encounter CommandInteractionPayloadMixin with a body.

wasabii added a commit that referenced this issue Jan 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants