Stanislau Listratsenka
Stanislau Listratsenka

Reputation: 680

Accidental override: The following declarations have the same JVM signature error on specific classes hierarchy

Here I found many similar questions, but not one solution did not help me because of the specifics of my problem. I have the following class hierarchy:

com.package.ParentInterface.java

public interface ParentInterface {
    void setMessages(Collection<String> var1);
}

com.package.ParentClass.java

public class ParentClass {
    protected Collection messages;

    public void setMessages(Collection messages)
    {
        this.messages = messages;
    }
}

com.package.ChildClass.java

public class ChildClass extends ParentClass implements ParentInterface {
}

com.package.KotlinClass.kt

class KotlinClass: ChildClass()

In the last Kotlin class I have following error: `Class 'KotlinClass' is not abstract and does not implement base class member public abstract fun setMessages(var1: (Mutable)Collection!): Unit defined in com.package.ChildClass.

When I accept the proposal of generating a method implementation using the IDE, I have:

override fun setMessages(var1: MutableCollection<String>?) { }

and I get the following error on the generated method:

Accidental override: The following declarations have the same JVM signature (setMessages(Ljava/util/Collection;)V):

And I can only change KotlinClass, because other classes are classes of a third-party library in Java. Help someone, please, I have already spent a lot of time on this problem.

Upvotes: 3

Views: 3394

Answers (3)

Forichok
Forichok

Reputation: 1

I encountered a JVM signature clash in Kotlin when working with a class that interacts with Java. The issue was with two setErrorMessages methods having the same JVM signature after Kotlin-to-Java bytecode compilation. To resolve this, I extended a Java class and overrode the method in Kotlin, ensuring compatibility and avoiding the clash. Here's the solution:

public class KotlinJiraWebActionSupport extends JiraWebActionSupport {

  @Override
  public void setErrorMessages(Collection errorMessages) {
    this.errorMessages = errorMessages;
  }
}

Upvotes: 0

Jfm Meyers
Jfm Meyers

Reputation: 151

I had a similar issue to this one however it was in how the class inherentence was being worked out. it involved a function getInfo being defined with both nullable and nonullable arguments

class ChangeFormNPC(input: ByteBuffer, flags: Flags.Int, context: ESSContext) : ess.GeneralElement(), ChangeFormData {
override fun getInfo(analysis: resaver.Analysis?, save: ess.ESS?): String { return ""}
}

what i mean by this is that in the above class definition ess.GeneralElement() was where the problem was occurring

in that other class

open class GeneralElement protected constructor() : Element {
open fun getInfo(analysis: Analysis, save: ESS): String { return "" }
}

error message observed

<somepath>\ChangeFormNPC.kt: (42, 5): Accidental override: The following declarations have the same JVM signature (getInfo(Lresaver/Analysis;Less/ESS;)Ljava/lang/String;):
    fun getInfo(analysis: Analysis, save: ESS): String defined in ess.ChangeFormNPC
    fun getInfo(analysis: Analysis?, save: ESS?): String defined in ess.ChangeFormNPC

the confusing part (at least to me at the time) was that it showed the same function with different null-able properties.

the fix was to add the nullable specifier to the arguments of getinfo in the GeneralElement class. This made the getinfo functions equal and removed the error.

Upvotes: 0

Alright, the answer is actually not as strict as it may seem - yes and no. You can overcome this limitation with pure kotlin but you will loose some functionality in the process/may introduce some unwanted but obvious errors in the process, so you should really investigate where this method is used before proceeding, because you need to basically "cut off" this method entirely in order to fix compilation errors.

So in your specific case I know you develop Atlassian plugin for Jira on Kotlin. That is kind of essential, because we know that this method can be avoided in your case.

The problem class is: com.atlassian.jira.web.action.JiraWebActionSupport

it implements interface: com.atlassian.jira.util.ErrorCollection

and the culprit method is: void setErrorMessages(Collection<String> var1);

ParentClass is webwork.action.ActionSupport

and it contains protected Collection errorMessages;

and that's how you can cut off this dead limb:

open class SpecificAction : JiraWebActionSupport() {
    override fun setErrorMessages(p0: MutableCollection<String>?) = TODO()
    ...
}

In your case Java override is of course more preferable, as you don't loose anything and don't introduce potential errors, but if you need only kotlin and sure that you don't/won't use this method - this little dirty hack will help.

Upvotes: 3

Related Questions