You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Corda 3.1中含java.sql.Timestamp的Collateral状态类反序列化报错求助

解决Corda 3.1中java.sql.Timestamp反序列化失败问题

你在Corda 3.1里遇到的这个问题很典型:包含java.sql.Timestamp成员的Collateral状态类反序列化时抛出java.io.NotSerializableException,哪怕已经把java.sql.Timestamp加入序列化白名单也没用。核心原因是Corda的序列化框架需要类有可被识别的反序列化构造函数,而java.sql.Timestamp的构造逻辑不符合它的要求。下面给你几个可行的解决方案:

推荐方案:改用Java 8时间API(java.time.Instant)

Corda官方本身就推荐使用Java 8引入的时间类,这些类天生兼容Corda的序列化机制,完全不需要额外配置:

  • 把Collateral类里的java.sql.Timestamp成员替换成java.time.Instant
  • 如果需要和数据库交互,只需要在数据访问层做简单转换:
    // Instant转Timestamp
    Timestamp dbTimestamp = Timestamp.from(yourInstant);
    // Timestamp转Instant
    Instant appInstant = dbTimestamp.toInstant();
    

备选方案1:为java.sql.Timestamp编写自定义序列化器

如果业务上必须保留java.sql.Timestamp类型,可以给它写一个自定义序列化器,让Corda知道怎么处理它的序列化和反序列化:

  1. 先写序列化器类:
    public class TimestampSerializer implements Serializer<Timestamp> {
        @Override
        public void serialize(Timestamp obj, SerializationOutput out) {
            // 序列化时只存时间戳的毫秒数
            out.writeLong(obj.getTime());
        }
    
        @Override
        public Timestamp deserialize(DeserializationInput in) {
            // 反序列化时用毫秒数重建Timestamp
            return new Timestamp(in.readLong());
        }
    
        @Override
        public boolean isSerializerForType(Class<?> type) {
            return Timestamp.class.equals(type);
        }
    }
    
  2. 然后在节点的node.conf配置文件里注册这个序列化器,同时确保白名单配置正确:
    serialization {
        whitelist = [
            "java.sql.Timestamp",
            "com.syne.cordapp.state.Collateral"
        ]
        customSerializers {
            "java.sql.Timestamp" = "com.your.package.TimestampSerializer"
        }
    }
    
  3. 最后重启Corda节点,让配置生效

备选方案2:在Collateral类中手动处理时间字段

另一种思路是不在状态类里直接存Timestamp,而是转成Long类型存储,反序列化时再转回来:

public class Collateral implements ContractState {
    // 用Long存储时间戳的毫秒数,替代直接存Timestamp
    private Long timestampMillis;

    // 对外提供获取Timestamp的方法
    public Timestamp getTimestamp() {
        return timestampMillis != null ? new Timestamp(timestampMillis) : null;
    }

    // 对外提供设置Timestamp的方法
    public void setTimestamp(Timestamp timestamp) {
        this.timestampMillis = timestamp != null ? timestamp.getTime() : null;
    }

    // 其他状态类的成员变量和实现方法...
}

这样处理后,Corda序列化时只会处理Long类型,完全避开了Timestamp的序列化问题。

内容的提问来源于stack exchange,提问作者balajimore

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:36:35