如何解决一起使用 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 举报,一经查实,本站将立刻删除。