-
Notifications
You must be signed in to change notification settings - Fork 1.7k
AVRO-1759: [java] Automatic union types for sealed classes #3436
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
AVRO-1759: [java] Automatic union types for sealed classes #3436
Conversation
|
@opwvhk got ahead of myself. Will endeavour to run them with the dispatch command going forward before opening the PR. Ready for review now |
lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectData.java
Outdated
Show resolved
Hide resolved
| // automatic sealed class polymorphic | ||
| try { | ||
| if (IS_SEALED_METHOD != null && Boolean.TRUE.equals(IS_SEALED_METHOD.invoke(element))) { | ||
| return (Class<?>[]) GET_PERMITTED_SUBCLASSES_METHOD.invoke(element); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this have checks for intermediate abstract classes ? And skip them.
E.g. Animal permits Mammal, Mammal permits Cat, Dog. Should Mammal be an item of the result ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@martin-g thanks for the review. Have made it skip the abstract and recursive.
lang/java/avro/src/main/java/org/apache/avro/reflect/ReflectData.java
Outdated
Show resolved
Hide resolved
lang/java/java17-test/src/test/java/org/apache/avro/reflect/TestPolymorphicEncoding.java
Outdated
Show resolved
Hide resolved
Co-authored-by: Martin Grigorov <martin-g@users.noreply.github.com>
….com/ashley-taylor/avro into AVRO-1759-sealed-polymorphic-support
|
I don't use Avro in Java myself, but I wonder if this should offer an opt-out. Maybe the developer has a class hierarchy only for selecting different in-memory representations and does not intend to encode it as an Avro union. I mean something similar to the .NET class BufferedLogRecord, which implements many of its properties as returning null by default, and derived classes override only those properties for which they are able to return a different value. So when the log buffering implementation gets a log entry and translates that to a BufferedLogRecord, it can choose a derived class at run time, depending on which properties it has been configured to save and whether the actual log entry has non-null values for those properties. (A log entry in .NET may contain references to objects that will be recycled for other purposes after the logging call returns, but before the log buffer is flushed. That's why the log entry cannot be stored in a log buffer as is.) OTOH, BufferedLogRecord is an abstract class, and I imagine a similar thing in Java would likewise be abstract and could not be automatically deserialized from a non-union Avro object, so perhaps types like that are unlikely to be used as Avro data. |
What is the purpose of the change
This pull request eliminates the need to manually configure the
@Unionannotation when using sealed classes. This should increase the times that Avro serialisation just works without needing to consult the documentation to address polymorphic types.I feel this is the best solution for AVRO-1759. Another approach would be to use a similar method to the reflections library. I feel that would be a step too far for this library.
It also addresses AVRO-1568 if third-party libraries start adding sealed classes as well.
Using reflection to read the sealed methods keeps this code compatible with Java 11.
Verifying this change
This change added tests and can be verified as follows:
Added new tests in the java17-test module to verify behaviour.
Documentation