我使用lib jackson-module-kotlin将json字符串解析为object .
我的问题是当我将字符串解析为枚举时,当我使用intellij启动时,我有这个堆栈跟踪:
引起:kotlin.reflect.jvm.internal.KotlinReflectionInternalError:尚未完全支持对内置Kotlin类型的反思 . 找不到公共最终val名称的元数据:kotlin.Enum中定义的kotlin.String [DeserializedPropertyDescriptor @ 212b316a]
当我使用maven启动时,我没有这个问题 .
我使用kotlin 1.1.51,使用intellij kotlin插件1.2.0-release-IJ2017.3-1,我的目标是JVM 1.8,我使用的是jackson-module-kotlin版本2.8.7
我该怎么办?
enum class CType { DEAL, FILE }
data class Code(val code: String, val type: CType)
fun testDeserialization() {
val mapper = jacksonObjectMapper()
// following line throws an exception:
mapper.readValue("""{"code":"A","type":"DEAL"}""", Code::class.java)
}
3 回答
Intellij最有可能使用kotlin编译器版本1.2.0(来自插件),它似乎不能正确支持反射 .
我建议你做以下其中一项:
将maven和intellij kotlin插件中的kotlin版本升级到更新版本(例如1.2.30) . 如果你这样做,你还必须将jackson-module-kotlin更新为> = 1.9,因为与kotlin 1.2不兼容(见here) .
在Intellij Idea设置中将kotlin编译器版本设置为1.1 .
在Intellij Idea和maven / gradle中使用相同版本的kotlin通常是个好主意 .
你需要使用与Kotlin 1.2.x兼容的Jackson的Kotlin模块,这包括这三个版本的模块:
2.9.4.1 (适用于任何2.9.x的 Jackson ,但最好最近使用)
2.8.11.1 ( Jackson 2.8.x)
2.7.9.1 ( Jackson 2.7.x)
否则,您将遇到库不匹配的问题 .
jackson-module-kotlin homepage将这些列为当前版本,但它们可能会更改,您可以检查各种Maven存储库搜索引擎,以查看哪些库版本可用以及它们在Kotlin上具有哪些依赖关系以查找匹配版本 .
另请注意,您可以导入
ObjectMapper
类的扩展名并使用已知类型,因此不是:你将会拥有:
或者:
使用擦除类型(即
Whatever::class.java
)通常很糟糕,因为这对于具有泛型类型参数的任何内容都不起作用,并且使用reified类型在反序列化为集合时也可以很好地工作 .你必须做一些事情 .
将 Jackson 依赖项更新为最新版本(现在,2.9.4) . 将 Kotlin 版本更新为等于或大于1.3.0的版本 .
确保将以下依赖项添加到build.gradle:
...然后你在 Jackson
ObjectMapper
上调用registerKotlinModule()
,你的枚举代码应该是这样的: