-
-
Notifications
You must be signed in to change notification settings - Fork 136
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
[Avro] Add support for @AvroEncode annotation #69
[Avro] Add support for @AvroEncode annotation #69
Conversation
public Object findDeserializer(Annotated am) { | ||
AvroEncode ann = _findAnnotation(am, AvroEncode.class); | ||
if (ann != null) { | ||
return CustomEncodingDeserializer.class; |
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.
AnnotationIntrospectorPair
does not support returning JsonDeserializer
instances, so using a HandlerInstantiator
to instantiate the deserializer with the correct context information.
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.
Hmmh. What do you mean by not supporting that? Since its Object
it should, and if not, that should be fixed...
@@ -113,6 +124,10 @@ public Object findSerializer(Annotated a) { | |||
if (a.hasAnnotation(Stringable.class)) { | |||
return ToStringSerializer.class; | |||
} | |||
AvroEncode ann = _findAnnotation(a, AvroEncode.class); | |||
if (ann != null) { | |||
return CustomEncodingSerializer.class; |
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.
AnnotationIntrospectorPair
does not support returning JsonSerializer
instances, so using a HandlerInstantiator
to instantiate the serializer with the correct context information.
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.
Ditto here, my reading would suggest instances or classes both should work?
(but I guess if there's problem with one there's with the other too)
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.
Or do you mean that since there isn't enough information, it may not be done? Contextualization will be done, however, so as long as serializer/deserializer implement Contextual(De)Serializer
, matching createContextual()
method will be called to give access to annotations, active configuration.
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.
The _isExplicitClassOrOb
check here requires that the primary return a Class
object - If you return an instance of a JsonSerializer
, _isExplicitClassOrOb
returns false and the secondary is used. If that's unintended behavior, then yeah, that should be fixed, and this code could be simplified to just return a JsonSerializer
instance with the context information already bound instead of deferring that to a custom HandlerInstantiator
(and the same for JsonDeserializer
above)
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.
I think changing this to
return true;
would fix the issue, and would actually make the OrOb
part of the method name make more sense, now that I think about it.
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.
Ok intention was to be reflected by method name: "Is (explicit) Class or Object". The only (?) kink there was simply that there are placeholder values to indicate "This is not a real value" -- just because Annotations themselves can NOT have value of null
, ever, so if a Class-value annotation optional property is desired, it MUST have value of some bogus class.
So, long way of saying: yes, returning a (de)serializer absolutely should be supported and if not, there's a bug. I'll file a bug on jackson-databind
and test this, for 2.9.
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.
@baharclerode Ok, filed & fixed FasterXML/jackson-databind#1581 -- it was regression from 2.8, but wasn't covered by unit tests (ironically enough I had added some tests for AnnotationIntrospectorPair
in 2.9... but not for this method).
Ok hmmh. This is quite elaborate, and I'll have to think carefully... since the problem is that I would ideally want to reduce or eventually even eliminate dependencies to the standard avro lib, wrt encoding/decoding. If this is only sort of isolated area and functionality only affects annotated types (which I think is the case), it may still be ok. And I am +1 on increased interoperability per se. I'll have to read over the code a bit more; I like many of the aspects (and we can probalby simplify some parts as per comments I added). |
You won't be able to completely remove the encoding dependencies from the avro lib and support this annotation - The annotation specifically requires a subtype of For example, the deserialization should already be decoupled, since that is handled by a wrapper that extends Serialization would probably require a similar pattern, but as long as the underlying implementation supports the same |
Agreed: I am ok with using annotations as well as simple interfaces (Decoder, Encoder) for this part. But note that my explicit goal (hoping to still get done for 2.9) is to remove actual usage of |
b9551a1
to
332eca6
Compare
332eca6
to
5756456
Compare
Your fix for |
@baharclerode Looks like there was yet another smaller issue, now fixed too: FasterXML/jackson-databind#1584 but I don't think it'd affect your changes here. |
This enables support for the
@AvroEncode
annotation, which is the avro equivalent of aJsonSerializer
/JsonDeserializer
.The serialization side of things was fairly straight-forward, since we can write directly to the underlying datum without worrying about parser state; Deserialization is a bit more tricky, since the parser inserts virtual tokens (start/end object, field names on records, etc.) that we need to consume those and otherwise ensure the parser state is updated so that deserialization control can be handed back to Jackson once the
CustomEncoding
has done its job.This is the last major piece of the puzzle that brings compatibility with the apache implementation up to an acceptable level for my use cases, so hoping it'll make the cut for 2.9 😃
I also re-enabled the tests that were ignored in 2.8 due to namespace changes, since the underlying code changes were themselves reverted when merged into master a while back.