Corda状态迁移中Kotlin类型擦除错误的正确处理方案咨询
解决Corda状态泛型集合字段类型变更的JVM签名冲突问题
在Corda状态升级中,直接修改泛型集合字段类型会触发序列化兼容性问题,而通过新增字段+废弃反序列化构造函数的方式又会因Kotlin类型擦除导致JVM签名冲突,以下是两种可靠的解决方式:
方法一:用@JvmName注解修改废弃构造函数的JVM签名
由于Kotlin泛型擦除后,Set<CustomDriverClass>和Set<String>在JVM层面均被视为Set类型,导致新旧构造函数签名重复。通过@JvmName为废弃构造函数指定唯一的JVM方法名,可彻底避免冲突:
data class CarA( val owners: List<Party>, val driversV2: Set<String>, override val linearId: UniqueIdentifier ) : LinearState { // 用于旧版本状态反序列化的废弃构造函数 @DeprecatedDeserialisationConstructor(1) @JvmName("CarADeprecatedConstructorV1") constructor( owners: List<Party>, drivers: Set<CustomDriverClass>, linearId: UniqueIdentifier ) : this( owners, drivers.map { it.driverId }.toSet(), // 完成旧类型到新类型的转换 linearId ) override val participants: List<AbstractParty> get() = owners }
方法二:为废弃构造函数添加占位参数
通过在废弃构造函数中添加一个无意义的占位参数(设置默认值,不影响反序列化逻辑),改变JVM层面的方法签名:
data class CarA( val owners: List<Party>, val driversV2: Set<String>, override val linearId: UniqueIdentifier ) : LinearState { @DeprecatedDeserialisationConstructor(1) constructor( owners: List<Party>, drivers: Set<CustomDriverClass>, linearId: UniqueIdentifier, @Suppress("UNUSED_PARAMETER") dummy: Boolean = true // 占位参数 ) : this( owners, drivers.map { it.driverId }.toSet(), linearId ) override val participants: List<AbstractParty> get() = owners }
临时调整字段位置的方式并不稳定,后续字段结构变动可能再次引发签名冲突。上述两种方法从根源解决了JVM签名重复问题,同时保证旧版本状态能正确反序列化为新版本状态。
内容的提问来源于stack exchange,提问作者Benjamin
相关产品推荐
相关产品推荐

