VerifyError:拒绝类Serializer

时间:2018-05-03 09:27:11

标签: android kotlin kotlinx.serialisation

我在使用kotlinx JSON序列化并在Android上使用@Serializer注释时遇到问题。问题只发生在某些API级别 - 似乎在API级别23以上工作,并在下面给出此错误:

java.lang.VerifyError: Rejecting class org.kethereum.wallet.model.KdfSerializer because it failed compile-time verification (declaration of 'org.kethereum.wallet.model.KdfSerializer' appears in /data/app/package.name-1/base.apk:classes3.dex)
        at org.kethereum.wallet.model.WalletCrypto.write$Self(Wallet.kt)
        at org.kethereum.wallet.model.WalletCrypto$$serializer.save(Wallet.kt)
        at org.kethereum.wallet.model.WalletCrypto$$serializer.save(Wallet.kt:15)
        at kotlinx.serialization.KOutput.writeSerializableValue(Serialization.kt:146)
        at kotlinx.serialization.KOutput.writeSerializableElementValue(Serialization.kt:191)
        at org.kethereum.wallet.model.Wallet.write$Self(Wallet.kt)
        at org.kethereum.wallet.model.Wallet$$serializer.save(Wallet.kt)
        at org.kethereum.wallet.model.Wallet$$serializer.save(Wallet.kt:53)
        at kotlinx.serialization.KOutput.write(Serialization.kt:99)
        at kotlinx.serialization.json.JSON.stringify(JSON.kt:40)
        at kotlinx.serialization.json.JSON$Companion.stringify(JSON.kt:57)
        at org.kethereum.wallet.WalletFileKt.generateWalletFile(WalletFile.kt:30)

我为我的用例找到了一个解决方法 - 但是我很想了解这个问题。 这样做时:

@Serializable
data class WalletCrypto(
        var cipher: String,
        var ciphertext: String,
        var cipherparams: CipherParams,
        var kdf: String,
        @Serializable(with = KdfSerializer::class)
        var kdfparams: KdfParams,
        var mac: String) {

        object KdfSerializer : KSerializer<KdfParams> {
            override val serialClassDesc = SerialClassDescImpl("KDFSerializer")

            override fun load(input: KInput) = throw NotImplementedError("loading WalletCrypto is not implemented - use WalletCryptoForImport instead")

            override fun save(output: KOutput, obj: KdfParams) = when (obj) {
                        is ScryptKdfParams -> output.write(obj)
                        is Aes128CtrKdfParams -> output.write(obj)
                }
        }
}

而不是:

@Serializable
data class WalletCrypto(
        var cipher: String,
        var ciphertext: String,
        var cipherparams: CipherParams,
        var kdf: String,
        @Serializable(with = KdfSerializer::class)
        var kdfparams: KdfParams,
        var mac: String) {

        @Serializer(forClass = KdfParams::class)
        object KdfSerializer : KSerializer<KdfParams> {
                override fun save(output: KOutput, obj: KdfParams) = when (obj) {
                        is ScryptKdfParams -> output.write(obj)
                        is Aes128CtrKdfParams -> output.write(obj)
                }
        }
}
问题消失了。所以问题似乎源于使用@Serializer注释。 KdfParams是一个密封的课程:

sealed class KdfParams {
    abstract var dklen: Int
    abstract var salt: String?
}

0 个答案:

没有答案