Håkan Lantz created CAMEL-22625:
-----------------------------------
Summary: AvroDataFormat unmarshal fails for union with logicalType
Key: CAMEL-22625
URL: https://issues.apache.org/jira/browse/CAMEL-22625
Project: Camel
Issue Type: Bug
Components: camel-avro
Affects Versions: 4.14.1
Reporter: Håkan Lantz
Attachments: DateRecord-1.avsc, DateRecordTest.java
When using optional logical types in avro for dates and time stamps unmarshal
fails with exception:
{noformat}
ClassCastException: class java.lang.Integer cannot be cast to class
java.time.LocalDate (java.lang.Integer and java.time.LocalDate are in module
java.base of loader 'bootstrap')
{noformat}
Here is a sample avro schema that illustrates that:
{code:json}
{
"type": "record",
"name": "DateRecord",
"namespace": "se.replyto.avro.test",
"fields": [
{
"name": "date",
"type": [
"null",
{
"type": "int",
"logicalType": "date"
}
],
"default": null
},
{
"name": "timestamp",
"type": [
"null",
{
"type": "long",
"logicalType": "timestamp-millis"
}
],
"default": null
}
]
}
{code}
This can be reproduced by generating the DateRecord class using the maven
avro-maven-plugin and try it with the following sample route builder:
{code:java}
AvroDataFormat avroDataFormat = new AvroDataFormat(DateRecord.SCHEMA$);
avroDataFormat.setInstanceClassName(DateRecord.class.getName());
from("direct:unmarshal")
.unmarshal(avroDataFormat).id("avro-unmarshal")
.to("mock:unmarshaled");
{code}
A fix for this is to override the unmarshal method and create a
SpecificDatumReader for the instanceClassName instead of creating it from a
SpecificData using the class loader of the avro schema.
{code:java}
AvroDataFormat avroDataFormat = new AvroDataFormat(DateRecord.SCHEMA$) {
@Override
public Object unmarshal(Exchange exchange, InputStream inputStream) throws
Exception {
String instanceClassName = getInstanceClassName();
if ( null != instanceClassName) {
Class<?> clazz = Class.forName(instanceClassName);
if (null != clazz) {
Decoder decoder =
DecoderFactory.get().binaryDecoder(inputStream, null);
DatumReader<?> reader = new SpecificDatumReader<>(clazz);
return reader.read(null, decoder);
}
}
return super.unmarshal(exchange, inputStream);
}
};
{code}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)