微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

一起使用 Ktor、Kmongo 和 kotlinx.serialization 导致 ClassCastException ......我做错了什么?

如何解决一起使用 Ktor、Kmongo 和 kotlinx.serialization 导致 ClassCastException ......我做错了什么?

https://github.com/reticent-monolith/winds_server 是 github 存储库,如果有人觉得在那里更容易找到的话。

我正在尝试将 KMongo 和 Ktor 与 Kotlin 的序列化模块一起使用,但创建 MongoClient 会导致以下异常:

java.lang.classCastException: class org.litote.kmongo.serialization.SerializationCodecRegistry cannot be cast to class org.bson.codecs.configuration.CodecProvider (org.litote.kmongo.serialization.SerializationCodecRegistry and org.bson.codecs.configuration.CodecProvider are in unnamed module of loader 'app')
    at org.litote.kmongo.service.ClassMappingTypeService$DefaultImpls.codecRegistry(ClassMappingTypeService.kt:83)
    at org.litote.kmongo.serialization.SerializationClassMappingTypeService.codecRegistry(SerializationClassMappingTypeService.kt:40)
    at org.litote.kmongo.serialization.SerializationClassMappingTypeService.coreCodecRegistry(SerializationClassMappingTypeService.kt:97)
    at org.litote.kmongo.service.ClassMappingType.coreCodecRegistry(ClassMappingType.kt)
    at org.litote.kmongo.service.ClassMappingTypeService$DefaultImpls.codecRegistry$default(ClassMappingTypeService.kt:79)
    at org.litote.kmongo.KMongo.configureRegistry$kmongo_core(KMongo.kt:79)
    at org.litote.kmongo.KMongo.createClient(KMongo.kt:70)
    at org.litote.kmongo.KMongo.createClient(KMongo.kt:57)
    at org.litote.kmongo.KMongo.createClient(KMongo.kt:47)
    at org.litote.kmongo.KMongo.createClient(KMongo.kt:39)
    at com.reticentmonolith.repo.MongodispatchRepo.<init>(MongodispatchRepo.kt:11)
    at com.reticentmonolith.ApplicationKt.<clinit>(Application.kt:14)
    ... 23 more

我在 build.gradle 中遗漏了什么吗?

buildscript {
    repositories {
        mavenCentral()
    }
    
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
    }
}

plugins {
    id 'org.jetbrains.kotlin.jvm' version '1.5.10'
    id 'org.jetbrains.kotlin.plugin.serialization' version '1.5.10'
    id 'application'
}

group 'com.reticentmonolith'
version '0.0.1-SNAPSHOT'
mainClassName = "io.ktor.server.netty.EngineMain"

sourceSets {
    main.kotlin.srcDirs = main.java.srcDirs = ['src']
    test.kotlin.srcDirs = test.java.srcDirs = ['test']
    main.resources.srcDirs = ['resources']
    test.resources.srcDirs = ['testresources']
}

repositories {
    mavenLocal()
    mavenCentral()
}

dependencies {
//    KOTLIN
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"

//    KTOR
    implementation "io.ktor:ktor-server-netty:$ktor_version"
    implementation "ch.qos.logback:logback-classic:$logback_version"
    implementation "io.ktor:ktor-server-core:$ktor_version"
    testImplementation "io.ktor:ktor-server-tests:$ktor_version"
    implementation "io.ktor:ktor-serialization:$ktor_version"

//    MONGO
    implementation group: 'org.mongodb',name: 'mongo-java-driver',version: '3.12.8'

//    KOTLINX SERIALIZATION
    implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.1"

//    KMONGO
    implementation 'org.litote.kmongo:kmongo-serialization:4.2.7'
    implementation group: 'org.litote.kmongo',name: 'kmongo-id-serialization',version: '4.2.7'

//    KBSON (optional dependency for KMONGO and Serialization)
    implementation "com.github.jershell:kbson:0.4.4"

}

这是我的 MongoClient 类:

import com.mongodb.client.MongoDatabase
import com.reticentmonolith.models.dispatch
import java.time.LocalDate

import org.litote.kmongo.*

class MongodispatchRepo: dispatchRepoInterface {

    private val client = KMongo.createClient()
    private val database: MongoDatabase = client.getDatabase("zw")
    private val windsData = database.getCollection<dispatch>("winds")


    override fun createdispatch(dispatch: dispatch) {
        windsData.insertOne(dispatch)
    }

    override fun getAlldispatches(): Map<String,List<dispatch>> {
        val list = windsData.find().toList()
        return mapOf("dispatches" to list)
    }

    override fun getdispatchesByDate(date: LocalDate): Map<String,List<dispatch>> {
        return mapOf("dispatches" to windsData.find(dispatch::date eq date).toList())
    }

    override fun getdispatchesByDaterange(start: LocalDate,end: LocalDate): Map<String,List<dispatch>> {
        return mapOf("dispatches" to windsData.find(dispatch::date gte(start),dispatch::date lte(end)).toList())
    }

    override fun getdispatchById(id: Id<dispatch>): dispatch? {
        return windsData.findOneById(id)
    }

    override fun updatedispatchById(id: Id<dispatch>,update: dispatch): Boolean {
        val olddispatch = getdispatchById(id)
        if (olddispatch != null) {
            update.date = olddispatch.date
            update._id = olddispatch._id
            windsData.updateOneById(id,update)
            return true
        }
        return false
    }

    override fun updateLastdispatch(update: dispatch): Boolean {
        val lastdispatch = getLastdispatch() ?: return false
        update.date = lastdispatch.date
        update._id = lastdispatch._id
        windsData.updateOneById(lastdispatch._id,update)
        return true
    }

    override fun deletedispatchById(id: Id<dispatch>) {
        windsData.deleteOne(dispatch::_id eq id)
    }

    override fun getLastdispatch(): dispatch? {
        val todaysdispatches = getdispatchesByDate(LocalDate.Now())
        if (todaysdispatches.isEmpty()) return null
        return todaysdispatches["dispatches"]?.last()
    }

    override fun addSpeedsToLastdispatch(line4: Int?,line3: Int?,line2: Int?,line1: Int?) {
        val lastdispatch = getLastdispatch() ?: return
        lastdispatch.riders.get(4)?.speed = line4
        lastdispatch.riders.get(3)?.speed = line3
        lastdispatch.riders.get(2)?.speed = line2
        lastdispatch.riders.get(1)?.speed = line1
        updateLastdispatch(lastdispatch)
    }

    fun purgeDatabase() {
        windsData.deleteMany(dispatch::comment eq "")
    }
}

还有我的 Application.kt for Ktor:

package com.reticentmonolith

import com.reticentmonolith.models.createExampledispatches
import io.ktor.application.*
import io.ktor.response.*
import io.ktor.routing.*
import io.ktor.http.*
import com.reticentmonolith.repo.MongodispatchRepo
import io.ktor.features.*
import io.ktor.serialization.*
import kotlinx.serialization.json.Json
import org.litote.kmongo.id.serialization.IdKotlinXSerializationModule

val repo = MongodispatchRepo()

fun main(args: Array<String>) = io.ktor.server.netty.EngineMain.main(args)

@Suppress("unused") // Referenced in application.conf
@kotlin.jvm.JvmOverloads
fun Application.module(testing: Boolean = false) {

    install(ContentNegotiation) {
        json(
            Json { serializersModule = IdKotlinXSerializationModule  },contentType = ContentType.Application.Json
        )
    }

    repo.purgeDatabase()
    val dispatchList = repo.getAlldispatches()["dispatches"]
    if (dispatchList != null && dispatchList.isEmpty()) {
        createExampledispatches(0).forEach {
            repo.createdispatch(it)
            println("######## date: ${it.date} ################")
        }
    }

    routing {
        get("/dispatches/") {
            call.response.status(HttpStatusCode.OK)
            val dispatches = repo.getAlldispatches()
            println("dispatches from Mongo: $dispatches")
            println("dispatches encoded for response: $dispatches")
        }
    }
}


最后是被序列化的类:

package com.reticentmonolith.models

import com.reticentmonolith.serializers.DateSerializer
import com.reticentmonolith.serializers.TimeSerializer
import kotlinx.serialization.Contextual
import org.litote.kmongo.*
import kotlinx.serialization.Serializable
import java.time.LocalDate
import java.time.LocalTime

@Serializable
data class dispatch(
    var riders: MutableMap<Int,@Contextual Rider?> = mutableMapOf(
        1 to null,2 to null,3 to null,4 to null
    ),var comment: String = "",var wind_degrees: Int,var wind_speed: Double,var winds_instructor: String,var bt_radio: String,var _id: @Contextual Id<dispatch> = newId(),//    @Serializable(with=DateSerializer::class)
    @Contextual var date: LocalDate = LocalDate.Now(),//    @Serializable(with=TimeSerializer::class)
    @Contextual var time: LocalTime = LocalTime.Now()
)

fun createExampledispatches(amount: Int): Collection<dispatch> {
    val dispatches = mutablelistof<dispatch>()
    for (i in 0..amount) {
        dispatches.add(dispatch(
            bt_radio = "BT Instructor",winds_instructor = "Winds Instructor",wind_speed = 20.5,wind_degrees = 186
        ).apply {
            this.riders[2] = Rider(67,front_slider = Slider.BLACK,trolley = 125)
            this.riders[3] = Rider(112,front_slider = Slider.NEW_RED,rear_slider = Slider.YELLOW,trolley = 34)
        })
    }
    return dispatches
}

非常感谢任何帮助:) 谢谢!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。