22

I've recently started expirementing with Kotlin and started a Spring Boot pet project using Kotlin.

I'm trying to integrate a custom User domain object to Spring Security and thus want to implement the UserDetails inteface.

Given my domain User object below:

import org.springframework.data.annotation.Id as DocumentId
import org.springframework.data.mongodb.core.mapping.Document
import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.authority.AuthorityUtils
import org.springframework.security.core.userdetails.UserDetails

@Document
data class User(@DocumentId val id: String? = null,
                val username: String = "",
                val password: String = "",
                val email: String = "",
                val name: String? = null,
                val surname: String? = null) : UserDetails {

    override fun isCredentialsNonExpired(): Boolean = true

    override fun isAccountNonExpired(): Boolean = true

    override fun isAccountNonLocked(): Boolean = true

    override fun getAuthorities(): MutableCollection<out GrantedAuthority> = AuthorityUtils.createAuthorityList("USER")

    override fun isEnabled(): Boolean = true
}

I get the following errors:

  1. Accidental override: The following declarations have the same JVM signature (getUsername()Ljava/lang/String;): public final fun < get-username>(): Kotlin.String, public abstract fun getUsername(): Kotlin.String!

  2. Accidental override: The following declarations have the same JVM signature (getPassword()Ljava/lang/String;): public final fun < get-password>(): Kotlin.String, public abstract fun getPassword(): Kotlin.String!

Since my User class already has a method getUsername(): Kotlin.String also implement the method getUsername(): Kotlin.String! ?

How am I supposed to resolve such an error, other than using the @JvmName on the property's getter and setter?

feugatos
  • 663
  • 6
  • 15
  • 1
    Possible duplicate of [Accidental override: The following declarations have the same JVM signature](https://stackoverflow.com/questions/44035263/accidental-override-the-following-declarations-have-the-same-jvm-signature) – Nicolás Carrasco-Stevenson Apr 12 '18 at 09:10
  • This question has a more detailed answer [here](https://stackoverflow.com/questions/44035263/accidental-override-the-following-declarations-have-the-same-jvm-signature). Although it uses Android specific code, the underlying principle is the same – Nicolás Carrasco-Stevenson Apr 12 '18 at 09:11

1 Answers1

38

The problem here is that it's impossible for a property getter to override a function from a supertype, from Kotlin's point of view. To workaround it, you can prevent the compiler from generating getters by making your properties private and implement required methods from supertypes manually, for example:

data class User(
    private val username: String = ""
    ...
): UserDetails {
    override fun getUsername() = username
    ...
}
Alexander Udalov
  • 31,429
  • 6
  • 80
  • 66
  • I encountered similar problems, https://stackoverflow.com/questions/45901531/how-to-create-a-data-class-implements-spring-secuirty-specific-userdetails, but if I added `private`, I found it destroyed destruction operation. – Hantsy Aug 27 '17 at 06:35