Skip to content

Conversation

@ashley-taylor
Copy link
Contributor

What is the purpose of the change

This pull request eliminates the need to manually configure the @Union annotation 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

  • Does this pull request introduce a new feature? (yes)
  • If yes, how is the feature documented? Built-in Java 17+ language feature now works without manual configuration.

@github-actions github-actions bot added the Java Pull Requests for Java binding label Jul 19, 2025
@ashley-taylor
Copy link
Contributor Author

@martin-g @opwvhk
Another PR. Not related to my goal to add record support, but an unrelated, simpler Java 17+ feature

Thanks

@ashley-taylor
Copy link
Contributor Author

@opwvhk got ahead of myself. Will endeavour to run them with the dispatch command going forward before opening the PR. Ready for review now

// 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);
Copy link
Member

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 ?

Copy link
Contributor Author

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.

@KalleOlaviNiemitalo
Copy link
Contributor

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Java Pull Requests for Java binding

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants