quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.87k stars 2.71k forks source link

Unable to serialise avro optional Decimal #20845

Closed msillence closed 3 years ago

msillence commented 3 years ago

Describe the bug

Avro union types of Decimal do not serialise but throw

2021-10-18 17:51:46,311 ERROR [io.sma.rea.mes.kafka] (smallrye-kafka-producer-thread-0) SRMSG18212: Message org.eclipse.microprofile.reactive.messaging.Message$8@5702ccea was not sent to Kafka topic 'com.fnz.test.sink' - nacking message: org.apache.kafka.common.errors.SerializationException: Error serializing Avro message
Caused by: org.apache.avro.UnresolvedUnionException: Not in union ["null",{"type":"bytes","logicalType":"decimal","precision":13,"scale":6}]: 0.26268382480788643
    at org.apache.avro.generic.GenericData.resolveUnion(GenericData.java:877)
    at org.apache.avro.generic.GenericDatumWriter.resolveUnion(GenericDatumWriter.java:272)
    at org.apache.avro.generic.GenericDatumWriter.writeWithoutConversion(GenericDatumWriter.java:143)
    at org.apache.avro.specific.SpecificDatumWriter.writeField(SpecificDatumWriter.java:98)
    at org.apache.avro.generic.GenericDatumWriter.writeRecord(GenericDatumWriter.java:210)
    at org.apache.avro.specific.SpecificDatumWriter.writeRecord(SpecificDatumWriter.java:83)
    at org.apache.avro.generic.GenericDatumWriter.writeWithoutConversion(GenericDatumWriter.java:131)
    at org.apache.avro.generic.GenericDatumWriter.write(GenericDatumWriter.java:83)
    at org.apache.avro.generic.GenericDatumWriter.write(GenericDatumWriter.java:73)
    at io.confluent.kafka.serializers.AbstractKafkaAvroSerializer.serializeImpl(AbstractKafkaAvroSerializer.java:135)
    at io.confluent.kafka.serializers.KafkaAvroSerializer.serialize(KafkaAvroSerializer.java:61)
    at org.apache.kafka.common.serialization.Serializer.serialize(Serializer.java:62)
    at org.apache.kafka.clients.producer.KafkaProducer.doSend(KafkaProducer.java:925)
    at org.apache.kafka.clients.producer.KafkaProducer.send(KafkaProducer.java:885)
    at io.smallrye.reactive.messaging.kafka.impl.ReactiveKafkaProducer.lambda$send$3(ReactiveKafkaProducer.java:102)

Serialisers all seem to work when I use them directly - either using Avro or using the KafkaAvroSerializer but when they are used within quarkus messages fail to serialise

Expected behavior

serialised and sent messages

Actual behavior

Exception and messages not sent

How to Reproduce?

Check out project:

https://github.com/msillence/quarkus-avro-decimal-bug

docker-compose up -d

in the project home

add mskafka and schema-registry to your hosts file pointing to your localhost

Run the quarkus application and you will see serialisation errors every second

Run the unit tests and they all pass

Output of uname -a or ver

Linux JHC8700TP 4.19.128-microsoft-standard #1 SMP Tue Jun 23 12:58:10 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

Output of java -version

openjdk version "17" 2021-09-14

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.3.0.Final

Build tool (ie. output of mvnw --version or gradlew --version)

apache-maven-3.8.1

Additional information

I have been trying to capture how the serialiser is constructed in the tests here:

https://github.com/msillence/quarkus-avro-decimal-bug/blob/master/src/test/java/com/fnz/schema/SinkValueTest.java

specifically the first tests is meant to be similar to how the serialiser is constructed in quarkus but it all works under test so I feel this is difficult to pin on either avro or the confluent kafak serialiser

quarkus-bot[bot] commented 3 years ago

/cc @cescoffier, @michalszynkiewicz, @ozangunalp, @phillip-kruger

msillence commented 3 years ago

Debugging I've got as far as finding the SpecificData class that's being used has an empty conversionsByClass map - this is populated in the working unit tests

msillence commented 3 years ago

OK, that's odd, seems that SpecificData.getForSchema line 147 throws in clazz = Class.forName(className); So I'd guess it's a class loader issue?

The same code works fine using the same parameter in a unit test

michalszynkiewicz commented 3 years ago

@msillence docker-compose up returns:

ERROR: Network kafkanet declared as external, but could not be found. Please create the network manually using `docker network create kafkanet` and try again.

Should I do as suggested?

msillence commented 3 years ago

Yes, or I think you can delete the network definition at the end of the docker-compose fileOn 19 Oct 2021 12:48, Michał Szynkiewicz @.***> wrote: @msillence docker-compose up returns: ERROR: Network kafkanet declared as external, but could not be found. Please create the network manually using docker network create kafkanet and try again.

Should I do as suggested?

—You are receiving this because you were mentioned.Reply to this email directly, view it on GitHub, or unsubscribe.Triage notifications on the go with GitHub Mobile for iOS or Android.

msillence commented 3 years ago

I commented on an avro bug https://issues.apache.org/jira/browse/AVRO-2028 that looked related before generating this test case and raising it with Quarkus the latest comment points me at a recent fix - https://github.com/apache/avro/pull/1304

It sounds very much like it but the 1.11.0-SNAPSHOT didn't work for me - nor does running against a local build of 1.12.0-SNAPSHOT checked out today

msillence commented 3 years ago

Ahh I'm really sorry I just got round to debugging this and I see I now get a rounding error and it is in fact working with the snapshot

One additional point it works with my build of 1.12.0-SNAPSHOT from today not the 1.11.0-SNAPSHOT #Wed Aug 19 21:39:36 UTC 2020 SHA1 8ff660f1b70b588051257aced9ef6bf7a7b611ff

michalszynkiewicz commented 3 years ago

great, so IIUC it's not an issue in Quarkus then and it will be resolved when we move to 1.12. I'll close this one.

michalszynkiewicz commented 3 years ago

@msillence thanks a lot for getting to the bottom of it!

msillence commented 3 years ago

1.11.0 release would also fix it when they build a release.