扩展Corda序列化以用于第三方类

时间:2018-07-11 08:45:07

标签: corda

TL; DR;

我需要Corda从JDK序列化JSONObject。我怀疑我可以为其添加自定义解析器,但是我不知道该怎么做。

完整故事:

所以我有一堆类充当JSON api的semy型安全包装器。一个例子:

@CordaSerializable
class ClaimReq(val json: JSONObject) {
    val proverDid: String = json.getString("prover_did")
    val credDefId: String = json.getString("cred_def_id")
}

当我尝试通过Corda频道发送此类课程时出现了问题。系统在序列化org.json.JSONObject时遇到问题:

  

java.io.NotSerializableException:没有为org.json.JSONObject类找到反序列化的构造函数。       在net.corda.nodeapi.internal.serialization.amqp.SerializationHelperKt.constructorForDeserialization(SerializationHelper.kt:50)〜[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SchemaKt.fingerprintForObject(Schema.kt:456)〜[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SchemaKt.access $ fingerprintForObject(Schema.kt:1)〜[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SchemaKt $ fingerprintForType $ 3.invoke(Schema.kt:423)〜[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SchemaKt $ fingerprintForType $ 3.invoke(Schema.kt)〜[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SchemaKt.fingerprintWithCustomSerializerOrElse(Schema.kt:345)〜[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SchemaKt.fingerprintForType(Schema.kt:417)[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SchemaKt.fingerprintForObject(Schema.kt:459)[corda-node-api-3.1-corda.jar :?]       位于net.corda.nodeapi.internal.serialization.amqp.SchemaKt.access $ fingerprintForObject(Schema.kt:1)[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SchemaKt $ fingerprintForType $ 3.invoke(Schema.kt:423)[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SchemaKt $ fingerprintForType $ 3.invoke(Schema.kt)处[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SchemaKt.fingerprintWithCustomSerializerOrElse(Schema.kt:345)[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SchemaKt.fingerprintForType(Schema.kt:417)[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SchemaKt.fingerprintForType $ default(Schema.kt:352)[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SchemaKt.fingerprintForType(Schema.kt:328)[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.ObjectSerializer。(ObjectSerializer.kt:34)[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SerializerFactory $ makeClassSerializer $ 1.apply(SerializerFactory.kt:271)[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SerializerFactory $ makeClassSerializer $ 1.apply(SerializerFactory.kt:40)[corda-node-api-3.1-corda.jar :?]       在java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1688)[?:1.8.0_171]       在net.corda.nodeapi.internal.serialization.amqp.SerializerFactory.makeClassSerializer(SerializerFactory.kt:255)[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SerializerFactory.get(SerializerFactory.kt:100)[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SerializationOutput.writeObject $ node_api(SerializationOutput.kt:98)[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SerializationOutput.writeObject $ node_api $ default(SerializationOutput.kt:97)[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SerializationOutput.writeObject $ node_api(SerializationOutput.kt:78)[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SerializationOutput $ _serialize $ 1 $ 1.invoke(SerializationOutput.kt:64)[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SerializationOutput $ _serialize $ 1 $ 1.invoke(SerializationOutput.kt:22)[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SerializationHelperKt.withList(SerializationHelper.kt:401)[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SerializationOutput $ _serialize $ 1.invoke(SerializationOutput.kt:63)[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SerializationOutput $ _serialize $ 1.invoke(SerializationOutput.kt:22)[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SerializationHelperKt.withDescribed(SerializationHelper.kt:390)[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SerializationOutput._serialize $ node_api(SerializationOutput.kt:62)[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.SerializationOutput.serialize(SerializationOutput.kt:36)[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.amqp.AbstractAMQPSerializationScheme.serialize(AMQPSerializationScheme.kt:128)[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.SerializationFactoryImpl $ serialize $ 1 $ 1.invoke(SerializationScheme.kt:126)[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.SerializationFactoryImpl $ serialize $ 1 $ 1.invoke(SerializationScheme.kt:86)[corda-node-api-3.1-corda.jar :?]       在net.corda.core.serialization.SerializationFactory.withCurrentContext(SerializationAPI.kt:66)[corda-core-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.SerializationFactoryImpl $ serialize $ 1.invoke(SerializationScheme.kt:126)[corda-node-api-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.SerializationFactoryImpl $ serialize $ 1.invoke(SerializationScheme.kt:86)[corda-node-api-3.1-corda.jar :?]       在net.corda.core.serialization.SerializationFactory.asCurrent(SerializationAPI.kt:80)[corda-core-3.1-corda.jar :?]       在net.corda.nodeapi.internal.serialization.SerializationFactoryImpl.serialize(SerializationScheme.kt:126)[corda-node-api-3.1-corda.jar :?]       在net.corda.core.serialization.SerializationAPIKt.serialize(SerializationAPI.kt:221)[corda-core-3.1-corda.jar :?]       在net.corda.core.serialization.SerializationAPIKt.serialize $ default(SerializationAPI.kt:220)[corda-core-3.1-corda.jar :?]       在net.corda.node.services.statemachine.FlowStateMachineImpl.createSessionData(FlowStateMachineImpl.kt:353)[corda-node-3.1-corda.jar :?]       在net.corda.node.services.statemachine.FlowStateMachineImpl.send(FlowStateMachineImpl.kt:235)上[corda-node-3.1-corda.jar :?]       在net.corda.node.services.statemachine.FlowSessionImpl.send(FlowSessionImpl.kt:52)[corda-node-3.1-corda.jar :?]       在net.corda.node.services.statemachine.FlowSessionImpl.send(FlowSessionImpl.kt:56)[corda-node-3.1-corda.jar :?]       在com.luxoft.blockchainlab.corda.hyperledger.indy.flow.IssueClaimFlow $ Prover.call(IssueClaimFlow.kt:85)[main / :?]       在com.luxoft.blockchainlab.corda.hyperledger.indy.flow.IssueClaimFlow $ Prover.call(IssueClaimFlow.kt:71)[main / :?]       在net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:96)[corda-node-3.1-corda.jar :?]       在net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:44)[corda-node-3.1-corda.jar :?]       在co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1092)[quasar-core-0.7.9-jdk8.jar:0.7.9]       在co.paralleluniverse.fibers.Fiber.exec(Fiber.java:788)[quasar-core-0.7.9-jdk8.jar:0.7.9]

所以我用一个特殊的构造函数和一个吸气剂解决了这个问题:

@CordaSerializable
class ClaimReq(val json: JSONObject) {
    val proverDid: String = json.getString("prover_did")
    val credDefId: String = json.getString("cred_def_id")

    @ConstructorForDeserialization constructor(str: String) : this(JSONObject(str))
    val str = json.toString()
}

不幸的是,该解决方案要求在每个类声明中添加2行。有什么办法可以像超级类中那样抽象出来?还是我可以使用自定义解析器扩展Corda序列化以支持JSONObject

1 个答案:

答案 0 :(得分:1)

由Corda框架序列化的具有多个构造函数的任何类都需要用@ConstructorForDeserialization注释其中一个构造函数。显然,JSONObject中没有带有此批注的构造函数。

您需要为JSONObject类提供自定义序列化程序。在此处查看定义自定义序列化程序的示例:https://docs.corda.net/head/cordapp-custom-serializers.html#example

如果此序列化程序位于类路径上,则节点将在运行时使用它。