question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Unable to evolve Enum by appending new fields.

See original GitHub issue

When I have an enum serialized in the vault as this:

@CordaSerializable
enum class MyEnum { A, B, C }

and then in later version of my cordapp I update it to:

@CordaSerializationTransformEnumDefaults(
    CordaSerializationTransformEnumDefault("E", "C"),
    CordaSerializationTransformEnumDefault("D", "C")
)
@CordaSerializable
enum class MyEnum { A, B, C, D, E }

then I receive such exception: java.io.NotSerializableException: Constants have been reordered, additions must be appended to the end.

Looking at the unit tests it seems that they test this scenario: Node A receives serialized enum from node B. This received enum has new constants added and the required annotation added and node A has only “old” enum constants. Node A is able to deserialize as required transforms are described in the deserialized enum from node B. That seems to work nicely.

My scenario is vice versa. I have some enum in my vault and I just want to add new constants to it. After adding new constants and the annotation and starting up the nodes I try to retrieve a state with that enum but I get an aforementioned exception.

Same issue when appending a single new value. And the same issue when appending same value without using CordaSerializationTransformEnumDefaults (only using CordaSerializationTransformEnumDefault)

Happened on V3.1

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:9 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
marko-mets-gtcommented, Nov 22, 2018

I was trying to fix it myself and have come up with the following. Here it is checked whether the enum constants have been reordered: https://github.com/corda/corda/blob/release-V3.X/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/EnumEvolutionSerializer.kt#L111

When replicating my use case then ordinals is bigger (it has new constants which are found on the classpath) than serialisedOrds (it contains only ‘old’ constants which were present during serialization). As it is bigger, then filterNot finds those new constants and assumes that something was reordered and throws. I added an additional check to apply filterNot on ‘smaller’ collection, like that:

if (ordinals.size <= serialisedOrds.size) {
    if (ordinals.filterNot { serialisedOrds[it.value] == it.key }.isNotEmpty()) {
        throw NotSerializableException("Constants have been reordered, additions must be appended to the end")
    }
} else {
    if (serialisedOrds.filterNot { ordinals[it.value] == it.key }.isNotEmpty()) {
        throw NotSerializableException("Constants have been reordered, additions must be appended to the end")
    }
}

With this fix all existing tests in EnumEvolveTests passed and I was able to perform the enum update which I described in the issue description.

I know that in future versions of corda whole serialization will be overhauled but could you tell if this would be safe to do until I can start using newer corda?

0reactions
joeldudleycommented, Dec 11, 2018

Fixed.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to add an enum value to an AVRO schema in a FULL ...
Whenever I try to add a new value to the symbols it fails the compatibility check in the schema registry even though I...
Read more >
Safety Considerations When Using Enums in Avro Schemas
You aren't sure which Avro versions are in use, but are confident that your enum has known fixed cardinality, and will never have...
Read more >
Dealing with Enum Type in PostgreSQL - DEV Community ‍ ‍
Add Enum Value. As the product evolves, one realizes that package can be lost, broken, stolen, etc. New package state is needed.
Read more >
Should/Will Kafka Connect support schema evolution using ...
Since Avro 1.10.X specification, enum values support defaults, which makes schema evolution possible even when adding subjects (values) to an ...
Read more >
Enums
The new enum declaration defines a full-fledged class (dubbed an enum type). ... it allows you to add arbitrary methods and fields to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found