在单元测试“ LinearState”的简单实现时,如何解决抛出的“ NotSerializableException”

时间:2019-04-03 17:49:57

标签: corda

我有一个“ LinearState”的简单实现,其中唯一的参数是UniqueIdentifier。我有一个简单的合同。

但是,当我尝试通过单元测试进行测试时,我会不断收到“ NotSerializabeException”。

我正在使用Corda v4 Java模板。使用IntelliJ上的Gradle Runner测试设置。

我尝试使用@CordaSerializable注释类,并使用@ConstructorForDeserialization注释构造函数

@CordaSerializable
public class InvestorState implements LinearState {

    private final UniqueIdentifier linearId;

    @ConstructorForDeserialization
    public InvestorState(UniqueIdentifier id) {
        this.linearId = id;
    }
...
}
Error log:
data(net.corda.core.contracts.ContractState) -> Trying to build an object serializer for com.mycordapp.states.InvestorState, but it is not constructible from its public properties, and so requires a custom serialiser.

java.io.NotSerializableException: data(net.corda.core.contracts.ContractState) -> Trying to build an object serializer for com.mycordapp.states.InvestorState, but it is not constructible from its public properties, and so requires a custom serialiser.

at net.corda.serialization.internal.amqp.ObjectSerializer$Companion.make(ObjectSerializer.kt:18)
at net.corda.serialization.internal.amqp.DefaultLocalSerializerFactory.makeNonCustomSerializer(LocalSerializerFactory.kt:240)
...

2 个答案:

答案 0 :(得分:0)

我发现构造函数中列出的参数必须与声明的变量相同。

我的更正代码:

@BelongsToContract(InvestorContract.class) // note this is required for Corda v4
@CordaSerializable // not strictly necessary as this class implements LinearState
public class InvestorState implements LinearState {

    private final UniqueIdentifier linearId;

    @ConstructorForDeserialization // only necessary if there are multiple constructors
    public InvestorState(UniqueIdentifier linearId) {
        this.linearId = linearId;
    }
...
}

在我的情况下,将构造函数参数'id'更改为'linearId'即可解决问题

答案 1 :(得分:0)

请给我两美分,以备将来参考: 来自Corda文档:

建议Corda中的可序列化对象遵循以下规则,因为它们允许对不可变状态对象进行反序列化:

  • 用于构造函数中每个属性的Java Bean getter,名称形式为getX。例如,对于构造函数参数foo,必须有一个名为getFoo()的getter。

如果foo是布尔值,则可以选择将getter称为isFoo()(这就是为什么必须在打开参数名称的情况下编译该类的原因)

  • 一个构造函数,它采用您希望以序列化形式记录的所有属性。

这是序列化框架重建类实例的必需条件。

如果提供了多个构造函数,则序列化框架需要知道要使用哪个构造函数。 @ ConstructorForDeserialization 注释可用于指示哪个。

对于Kotlin类,如果没有@ConstructorForDeserialization批注,则将选择主构造函数。