Reputation: 53
I'm currently trying to create a parent class that can be serialized but has no own attributes. (They will be added in the inheriting classes)
For some reason there is no serializer()
-method being generated.
I checked the following things:
serialization-plugin
from JetBrains added to my build.gradle
-file.kotlinx.serialization.serializable
-annotation.Thank you for reading my question.
This is the exception:
java.lang.NullPointerException: Cannot invoke "me.trqhxrd.grapesrpg.impl.world.predefined.Void$Companion.serializer()" because "me.trqhxrd.grapesrpg.impl.world.predefined.Void.Companion" is null
at me.trqhxrd.grapesrpg.impl.world.BlockData.<clinit>(BlockData.kt:24) ~[GrapesRPG-1.0-SNAPSHOT-all.jar:?]
... 37 more
These code-snippets might be relevant:
build.gradle
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.6.21'
id 'org.jetbrains.kotlin.plugin.serialization' version '1.6.21'
id 'com.github.johnrengelman.shadow' version '7.1.2'
id 'java'
}
group = 'me.trqhxrd'
version = '1.0-SNAPSHOT'
repositories {
mavenCentral()
maven {
url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/'
}
maven {
url 'https://repo.codemc.org/repository/maven-public/'
}
maven {
url 'https://maven.wolfyscript.com/repository/public/'
}
maven {
url 'https://mvn.trqhxrd.de/releases'
}
}
dependencies {
testImplementation 'org.jetbrains.kotlin:kotlin-test'
testImplementation 'com.github.seeseemelk:MockBukkit-v1.18:1.24.1'
compileOnly 'org.spigotmc:spigot-api:1.18.2-R0.1-SNAPSHOT'
compileOnly 'org.eclipse.aether:aether-api:1.1.0'
compileOnly 'org.eclipse.aether:aether-spi:1.1.0'
compileOnly 'org.eclipse.aether:aether-connector-basic:1.1.0'
compileOnly 'org.eclipse.aether:aether-transport-file:1.1.0'
compileOnly 'org.eclipse.aether:aether-transport-http:1.1.0'
compileOnly 'org.apache.maven:maven-aether-provider:3.3.9'
compileOnly 'org.apache.maven.resolver:maven-resolver-connector-basic:1.8.0'
compileOnly 'org.jetbrains.exposed:exposed-core:0.38.2'
compileOnly 'org.jetbrains.exposed:exposed-jdbc:0.38.2'
compileOnly 'org.jetbrains.exposed:exposed-dao:0.38.2'
compileOnly 'org.xerial:sqlite-jdbc:3.36.0.3'
compileOnly 'com.zaxxer:HikariCP:5.0.1'
compileOnly 'org.slf4j:slf4j-nop:2.0.0-alpha7'
compileOnly 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21'
compileOnly 'org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.3.2'
compileOnly 'org.jetbrains.kotlin:kotlin-reflect:1.6.21'
compileOnly 'com.google.guava:guava:31.1-jre'
shadow 'org.bstats:bstats-bukkit:3.0.0'
shadow 'me.trqhxrd:menus:1.2.1'
shadow 'com.wolfyscript.wolfyutils.spigot:wolfyutils-spigot:4.16.1.0'
shadow 'de.tr7zw:item-nbt-api:2.9.2'
shadow 'de.tr7zw:nbt-injector:2.9.2'
}
test {
useJUnitPlatform()
}
compileKotlin {
kotlinOptions.jvmTarget = '1.8'
}
compileTestKotlin {
kotlinOptions.jvmTarget = '1.8'
}
tasks.register('installPlugin', Copy) {
dependsOn 'shadowJar'
from layout.buildDirectory.dir("$buildDir/libs/GrapesRPG-1.0-SNAPSHOT-all.jar")
into layout.buildDirectory.dir("$projectDir/Server/plugins")
}
configurations {
shadow
compile.extendsFrom provided
provided.extendsFrom shadow
}
shadowJar {
relocate 'org.bstats', 'me.trqhxrd.shade.bstats'
configurations = [project.configurations.shadow]
from(project.sourceSets.main.output)
}
The parent class
package me.trqhxrd.grapesrpg.impl.world
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.decodeFromJsonElement
import kotlinx.serialization.json.jsonObject
import me.trqhxrd.grapesrpg.impl.world.predefined.Void
import me.trqhxrd.grapesrpg.util.ModuleKey
import me.trqhxrd.grapesrpg.api.world.BlockData as BlockDataAPI
@Serializable
abstract class BlockData(override val id: ModuleKey) : BlockDataAPI {
companion object {
val registry = mutableMapOf<ModuleKey, Pair<Class<out BlockData>, KSerializer<out BlockData>>>()
val KEY_VOID = ModuleKey("grapes", "void")
init {
registry[KEY_VOID] = Void::class.java to Void.serializer()
}
}
override fun save() = Json.encodeToString(this)
@Suppress("UNCHECKED_CAST")
override fun load(serialized: String) {
val key = Json.decodeFromJsonElement<ModuleKey>(
Json.decodeFromString<JsonObject>(serialized)["id"]!!.jsonObject
)
val serializer = registry[key]!!.second
val d = serializer.deserialize(Json.decodeFromString(serialized))
if (this::class.java.isAssignableFrom(d::class.java)) this.apply(d)
}
override fun apply(data: BlockDataAPI) {
if (!this::class.java.isAssignableFrom(data::class.java))
throw IllegalArgumentException(
"Can't load data from a class isn't assignable from the loading class. " +
"(Required: ${this::class.qualifiedName}, Received: ${data::class.qualifiedName})"
)
}
}
The child class
package me.trqhxrd.grapesrpg.impl.world.predefined
import kotlinx.serialization.Serializable
import me.trqhxrd.grapesrpg.impl.world.BlockData
import org.bukkit.event.block.BlockBreakEvent
import org.bukkit.event.block.BlockPlaceEvent
import org.bukkit.event.player.PlayerInteractEvent
@Serializable
class Void : BlockData(KEY_VOID) {
override fun onClick(event: PlayerInteractEvent) {}
override fun onBreak(event: BlockBreakEvent) {}
override fun onPlace(event: BlockPlaceEvent) {}
}
EDIT 1:
I try to create a new object of the Void
-class via the empty constructor.
EDIT 2:
All the dependencies are compileOnly
because this is a Minecraft-Plugin and most of the dependencies will be downloaded automatically by the Minecraft-Server. That way my Uber-Jar is smaller...
Upvotes: 0
Views: 1339
Reputation: 53
Well I just gave up and used Gson. If anyone finds an answer that doesn't just avoid the problem by removing the library feel free to post it here and I'll mark it as correct. Thank you for reading...
Upvotes: 2