Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin, how to overcome accidental override when extending plus implementing

I try to create a custom exception in kotlin, and also implement GraphQLError interface, which require the method getMessage().

If I try to implement the method, my IDE warns me that:

Accidental override: The following declarations have the same JVM signature (getMessage()Ljava/lang/String;): 
public open fun <get-message>(): String? defined in eu.mojo.presentation2018.error.ShopException
public open fun getMessage(): String defined in eu.mojo.presentation2018.error.ShopException

But if I remove it:

Class 'ShopException' is not abstract and does not implement abstract member
public abstract fun getMessage(): String! defined in graphql.GraphQLError

I searched for solution around the web, but all required some control over the field "message" that causes the conflict. In my case this control does not exists, since the field message is defined in Exception class that I try to extend.

Here is my class definition:

class ShopException(code:ErrorCode) : Exception(), GraphQLError {...}
like image 281
Alkis Mavridis Avatar asked May 12 '18 23:05

Alkis Mavridis


Video Answer


2 Answers

To keep most of my code in Kotlin I created a BaseException class in Java so that I can override errorMessage() instead of getMessage(). Now only my parent class is in Java and everything else works in Kotlin.

Java Base Class

import com.fasterxml.jackson.annotation.JsonIgnore;
import graphql.GraphQLError;

public abstract class BaseException extends RuntimeException implements GraphQLError {
    abstract String errorMessage();

    @Override
    public String getMessage() {
        return errorMessage();
    }

    @Override
    @JsonIgnore
    public StackTraceElement[] getStackTrace() {
        return super.getStackTrace();
    }
}

Kotlin Derived Class

class CredentialException : BaseException() {
    override fun errorMessage(): String = "Invalid credentials"
    override fun getErrorType(): ErrorType = ErrorType.ValidationError
    override fun getLocations(): MutableList<SourceLocation>? = null
}
like image 154
조일현 Avatar answered Dec 11 '22 23:12

조일현


Currently (Kotlin 1.2.61) this isn't possible.

Here are some issues regarding that problem that probably did not get enough attention yet (some are only related as they rather mention properties in their constellation):

  • Add JVM-specific annotation to permit "accidental" overrides of interface members (depends whether one wants to have annotations to solve that issue)
  • Kotlin and Java have a different behaviour at class inference
  • Kotlin properties do not override Java-style getters and setters; a comment of that issue mentions a similar constellation
like image 20
Roland Avatar answered Dec 11 '22 23:12

Roland