Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Locking down the serialVersionUID in Kotlin

Tags:

kotlin

I've been battling the whole morning to lock down the serialVersionUID in a Kotlin class. I have a BaseModel which is extended by Project

abstract class BaseModel<T>(
        var id: Int? = null,
        private val fileName: String,
        private val data: MutableList<T>,
        private val indices: MutableMap<Int, T>
) : Serializable {

  ...

   protected fun writeToDisk() {
       val oos = ObjectOutputStream(BufferedOutputStream(FileOutputStream(fetchFileName()))   )
       oos.writeObject(fetchData());
       oos.close();
   }


}

And the project class:

class Project(
        var name: String = "",
        var repo: String = ""

) : BaseModel<Project>(
        data = Data.projects,
        indices = Data.projectsIndex,
        fileName = "data/projects.dat"
), Serializable {

    ...

    override fun toString(): String {
        return "Project: id=${id}, name=${name}, repo=${repo}"
    }

}

Every time I write to Disk and then change anything in the class and try to read it back again, I would get:

java.io.InvalidClassException: com.jvaas.bob.model.Project; local class incompatible: stream classdesc serialVersionUID = 4156405178259085766, local class serialVersionUID = 2024101567466310467

I've tried adding:

private val serialVersionUID: Long = 1 

to all classes with no effect.

Some examples on StackOverflow were using serialVersionUid which had no effect either (I believe this is intelliJ lowercasing the last two letters for some reason)

@JvmStatic doesn't work here since it's not an object, I've tried making it non-private with no success.

like image 484
Jan Vladimir Mostert Avatar asked Dec 18 '22 13:12

Jan Vladimir Mostert


1 Answers

You can define serialVersionUID as a constant in a companion object:

abstract class BaseModel<T> : Serializable {
    companion object {
        private const val serialVersionUID: Long = -1
    }
}

Constants are compiled to fields, and fields of a companion are stored as static fields of the class that contains companion. Therefore you get what you need – a private static field serialVersionUID in your serializable class.

like image 126
Ilya Avatar answered Jan 16 '23 06:01

Ilya