I'm having a little trouble working on a small project in Desktop Compose. I have the 3 functions below:
package utilities
import com.google.gson.Gson
import serializables.Settings
import java.io.File
fun CheckSettingsFile () {
if (!File("settings.json").exists()) {
File("settings.json").createNewFile()
with(File("settings.json")) {
val settings = Settings("192.168.1.254","3344")
val gson = Gson()
gson.newBuilder().setPrettyPrinting()
val toWrite = gson.toJson(settings)
this.writeText(toWrite)
}
}
}
fun SaveSettings (s : Settings) {
val gson = Gson()
gson.newBuilder().setPrettyPrinting()
val serialized = gson.toJson(s)
try {
with(File("settings.json")) {
this.writeText(serialized)
}
} catch (err :Exception) {
println(err.message)
}
}
fun LoadSettings () : Settings {
val gson = Gson()
return gson.fromJson(File("settings.json").readText(), Settings::class.java)
}
While running from IntelliJ IDEA the code works perfectly, but after packaging as msi or exe for Windows I stumble in this error:
Unable to create instance of class serializables.Settings. Registering an InstanceCreator or a TypeAdapter for this type, or adding a no-args constructor may fix this problem.
I haven't tried to solve it like the error message suggests because I'd like to understand what causes the error in the first place.
Here's the gradle.settings.kts
:
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
plugins {
kotlin("jvm")
id("org.jetbrains.compose")
}
group = "com.eticket"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
google()
}
dependencies {
implementation("com.google.code.gson:gson:2.10.1")
implementation(compose.desktop.currentOs)
}
compose.desktop {
application {
mainClass = "MainKt"
nativeDistributions {
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb, TargetFormat.Exe)
packageName = "eTicket"
packageVersion = "1.0.0"
windows {
shortcut = true
iconFile.set(project.file("stamp-icon.ico"))
console = false
menu = true
}
}
}
}
Thanks to everyone who feels to share a hint!
Most likely your Settings
class does not have a no-args constructor, so you are currently implicitly relying on sun.misc.Unsafe
which is used by Gson to create an instance of this class, see GsonBuilder.disableJdkUnsafe()
for more details.
The class sun.misc.Unsafe
is part of the module jdk.unsupported
, so you can probably solve this by adding the following to your Gradle settings:
compose.desktop {
application {
...
nativeDistributions {
...
modules("jdk.unsupported")
}
}
}
(based on this comment)
However, note that Gson does not fully support Kotlin (see for example this issue), so it might be better to switch to a library with explicit Kotlin support, such as Moshi, Jackson or kotlinx-serialization.