diff --git a/lang/java/avro/src/main/java/org/apache/avro/io/parsing/Symbol.java b/lang/java/avro/src/main/java/org/apache/avro/io/parsing/Symbol.java index a18f3fdbcd5..7009de99735 100644 --- a/lang/java/avro/src/main/java/org/apache/avro/io/parsing/Symbol.java +++ b/lang/java/avro/src/main/java/org/apache/avro/io/parsing/Symbol.java @@ -475,6 +475,16 @@ public int findLabel(String label) { return i; } } + // AVRO-4135 We are a bit more flexible here since we have to deal with the C + // serializer being less strict, so + // we fall back to looking up unqualified names. + for (int i = 0; i < labels.length; i++) { + String candidate = labels[i]; + if (candidate != null && candidate.length() > label.length() + && candidate.charAt(candidate.length() - label.length() - 1) == '.' && candidate.endsWith(label)) { + return i; + } + } } return -1; } diff --git a/lang/java/avro/src/test/java/org/apache/avro/io/TestJsonDecoder.java b/lang/java/avro/src/test/java/org/apache/avro/io/TestJsonDecoder.java index 05057139600..39600af5d4d 100644 --- a/lang/java/avro/src/test/java/org/apache/avro/io/TestJsonDecoder.java +++ b/lang/java/avro/src/test/java/org/apache/avro/io/TestJsonDecoder.java @@ -92,4 +92,16 @@ void testIntWithError() throws IOException { JsonDecoder decoder = DecoderFactory.get().jsonDecoder(schema, record); Assertions.assertThrows(AvroTypeException.class, () -> reader.read(null, decoder)); } + + @Test + void testUnionTypeQualification() throws Exception { + final Schema schema = SchemaBuilder.unionOf().nullType().and() + .type(SchemaBuilder.record("r").namespace("space").fields().endRecord()).endUnion(); + GenericDatumReader reader = new GenericDatumReader<>(schema, schema); + JsonDecoder decoder = DecoderFactory.get().jsonDecoder(schema, "{\"space.r\": {}}"); + assertEquals("space.r", reader.read(null, decoder).getSchema().getFullName()); + // AVRO-4135: C json encoder uses unqualified types. + decoder = DecoderFactory.get().jsonDecoder(schema, "{\"r\": {}}"); + assertEquals("space.r", reader.read(null, decoder).getSchema().getFullName()); + } }