Matthew Layton
Matthew Layton

Reputation: 42260

Corda - Passing Anonymous Implementations Over RPC

Is it possible to pass anonymous object implementations over Corda's RPC interface? - For example:

Workflow

@CordaSerializable
interface ExampleInterface {
    val number: Int
}

@StartableByRPC
class SquareFlow(private val example: ExampleInterface) : FlowLogic<Int>() {
    
    @Suspendable
    override fun call(): Int = example.number * example.number
}

RPC Client

val value = object : ExampleInterface {
    override val number: Int = 5
}

return rpc.startFlowDynamic(SquareFlow::class.java, value).returnValue.getOrThrow()

Exception

net.corda.client.rpc.RPCException: java.util.List<*> -> Unable to create an object serializer for type class com.example.client.ExampleService$square$value$1: No unique deserialization constructor can be identified

Either annotate a constructor for this type with @ConstructorForDeserialization, or provide a custom serializer for it

Whilst this is an example, what I actually want to do is pass object : TypeReference<SomeType>(){} over RPC.

Upvotes: 0

Views: 86

Answers (1)

James Ronayne
James Ronayne

Reputation: 61

As per Corda's docs anonymous objects are not supported by their AMQP serialization which is used in the RPC client which you can read here. This is likely due to a public constructor being needed for serialization and deserialization I imagine.

Additionally I assume you are referencing Jackson's TypeReference class which uses generics which are only available at compile time. Due to how Corda's serialization works the generic won't be available at runtime so when the TypeReference is passed from the rpc application to the corda node the corda node will not know what the generic is. I haven't tried this myself but I believe some exception will be thrown whenever the flow attempts to suspend or possibly before in the RPC client.

You can probably pass a jackson JavaType class to a flow without a problem as I believe it is whitelisted as serializable in Corda by default, if not look at how to whitelist the class here using the SerializationWhitelist. You can obtain the JavaType by instantiating a TypeFactory and calling constructType(new TypeReference<SomeType> {}). then just pass the JavaType to your flows constructor.

Upvotes: 1

Related Questions