Reputation: 680
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
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
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
Reputation: 46
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