从Corda V2升级至V3后程序失效,请求排查序列化异常
NotSerializableException问题 刚把Corda从V2升到V3就踩了这个序列化的坑?太懂这种升级时突然崩掉的郁闷了!咱们先把错误信息的核心拎出来:
[ERROR] 16:02:31,129 [qtp1715876585-27] (ExampleApi.java:226) api.ExampleApi.myMethod - java.io.NotSerializableException: net.corda.core.contracts.TransactionState -> data(net.corda.core.contracts.ContractState) -> Constructor parameter - "parameter_2" - doesn't refer to a property of "class com.example.state.MyState" -> class com.example.state.MyState {}
这个报错直白得很:你的MyState类构造函数里有个叫parameter_2的参数,但这个参数并没有对应到类里的同名成员属性——而Corda V3对序列化的规则比V2严格太多,它要求合约状态类的构造参数必须和类的成员属性一一对应,且名字完全匹配。
具体解决步骤
第一步:检查
MyState的构造函数与属性定义
打开com.example.state.MyState类,看看是不是出现了这两种情况:要么构造函数里有parameter_2参数,但类里没定义对应的属性;要么属性名和参数名不匹配(比如参数是parameter_2,属性写成了param2)。举个典型的错误写法:
public class MyState implements ContractState { private final String param2; // 参数名和属性名不匹配,V3序列化直接报错 public MyState(String parameter_2) { this.param2 = parameter_2; } }修正后的正确写法:
public class MyState implements ContractState { private final String parameter_2; // 参数名与属性名完全一致 public MyState(String parameter_2) { this.parameter_2 = parameter_2; } // 别忘了给每个属性加getter方法,Corda序列化需要访问属性 public String getParameter_2() { return parameter_2; } }第二步:确保
MyState符合V3的序列化规范
除了参数-属性匹配,还要注意:- 所有成员属性必须是
final的(Corda状态本身是不可变的) - 每个属性都要有对应的getter方法
- 如果状态类有嵌套对象,嵌套类也要满足同样的序列化要求
- 所有成员属性必须是
第三步:清理缓存重新构建项目
旧的编译缓存可能会干扰新代码的生效,执行命令彻底清理后重新构建:./gradlew clean build
如果做完这些还是有问题,大概率是状态类继承结构或嵌套对象的序列化问题,但从当前报错来看,90%的概率就是构造参数和属性不匹配导致的,先解决这个问题再说!
内容的提问来源于stack exchange,提问作者s.Takahashi

