Corda V3.1创建状态及V2迁移至V3.1时遇java.io.NotSerializableException问题
解决Corda V3.1状态序列化异常:找不到序列化构造函数
嘿,我之前在Corda版本迁移和状态开发时也碰到过一模一样的坑,给你几个实际可行的排查和解决方向:
核心排查点
1. 确保状态类的访问权限与结构合规
- 你的合约状态类必须是public的,如果是嵌套在合约类里的内部类,一定要声明为
static(Java)或者去掉inner修饰符(Kotlin)——非静态内部类会隐含持有外部类的引用,序列化时会找不到正确的构造函数。 - 必须正确实现
ContractState接口,别漏了participants这个必填成员。
2. 构造函数的严格要求
Corda的序列化机制对构造函数有明确规则,哪怕你写了无参和带参构造,也可能因为权限或结构问题不生效:
- 无参构造函数必须是public的,不能是private/protected,序列化机制需要通过它来实例化对象。
- 如果你用Kotlin的data class,要注意默认无参构造是否存在:如果data class的参数没有默认值,Kotlin不会自动生成无参构造,必须显式声明,比如:
data class MyCustomState( val assetId: String, override val participants: List<AbstractParty> ) : ContractState { // 显式声明public无参构造,适配序列化 constructor() : this("", emptyList()) } - Java类的话,要保证无参构造是public,带参构造的参数顺序要和成员变量声明顺序一致,且能初始化所有成员。
3. 成员变量的序列化合规性
状态里的所有成员变量(包括嵌套对象)都必须是可序列化的:
- 自定义类型要添加
@CordaSerializable注解(Corda推荐),或者实现Java的Serializable接口。 - 避免使用Corda不支持的序列化类型,比如匿名内部类、未序列化的第三方类等。
4. 版本迁移的特殊注意事项
从Corda V2升级到V3.1时,序列化机制变得更严格:
- V2中可能允许的“宽松”序列化(比如非public构造、隐含引用)在V3.1里会直接触发异常,需要逐个检查状态类的序列化合规性。
- 如果是继承自自定义父类的状态,父类也必须满足所有序列化要求(public无参构造、成员可序列化等)。
异常信息参考
你碰到的异常如下:
[WARN ] 2018-04-12T17:40:09,773Z [Node thread-1] flow.[f1e07b24-6f07-4e2b-a9cf-c9f92c14985a].run - Terminated by unexpected exception {} java.io.NotSerializableException: net.corda.core.contracts.TransactionState -> data(net.corda.core.contracts.ContractState) -> No constructo...
内容的提问来源于stack exchange,提问作者Kid101
相关产品推荐
相关产品推荐

