Ivan A. Malich created AVRO-2902:
------------------------------------
Summary: ClassCastException in generated Java classes when used in
OSGi
Key: AVRO-2902
URL: https://issues.apache.org/jira/browse/AVRO-2902
Project: Apache Avro
Issue Type: Bug
Components: compatibility, logical types, tools
Affects Versions: 1.9.2
Environment: Karaf 4.2.8, 4.2.9
Reporter: Ivan A. Malich
Example schema:
{code:java}
{
"name": "ClientOrder",
"type": "record",
"namespace": "biz.sanwell.it.kafka.avsc",
"version":"1",
"fields": [
{ "name": "id", "type": { "type": "string", "logicalType":
"uuid" } },
{ "name": "name", "type": [ "null", "string" ], "default": null
},
{ "name": "creationDate", "type": { "type": "long",
"logicalType": "timestamp-millis" } },
{ "name": "orderStatus", "type": { "type": "string",
"logicalType": "uuid" }, "default": "6c311f46-b55b-11ea-b3de-0242ac130004" }
]
}
{code}
Generated by {{avro-maven-plugin}} POJO fragment:
{code:java}
...
@Override
@SuppressWarnings("unchecked")
public ClientOrder build() {
try {
ClientOrder record = new ClientOrder();
record.id = fieldSetFlags()[0] ? this.id : (java.util.UUID)
defaultValue(fields()[0]);
record.name = fieldSetFlags()[1] ? this.name : (java.lang.String)
defaultValue(fields()[1]);
record.creationDate = fieldSetFlags()[2] ? this.creationDate :
(java.time.Instant) defaultValue(fields()[2]);
record.orderStatus = fieldSetFlags()[3] ? this.orderStatus :
(java.util.UUID) defaultValue(fields()[3]); //this line causes exception
...
{code}
Example code causing exception:
{code:java}
public class TestRunner implements BundleActivator {
@Override
public void start(BundleContext context) throws Exception {
ClientOrder clientOrder = ClientOrder.newBuilder()
.setId(UUID.randomUUID())
.setCreationDate(Instant.now())
.build(); //this line causes exception
System.out.println(clientOrder.toString());
}
{code}
Exception:
{{...}}{{}}
{{ Error starting bundle 251: Activator start error in bundle
biz.sanwell.it.kafka.sw-kafka-avro-schemas [251].}}
{{...}}
{{Caused by: org.apache.avro.AvroRuntimeException:
java.lang.ClassCastException: class org.apache.avro.util.Utf8 cannot be cast to
class java.util.UUID (org.apache.avro.util.Utf8 is in unnamed module of loader
org.apache.felix.framework.BundleWiringImpl$BundleClassLoader @7579319f;
java.util.UUID is in module java.base of loader 'bootstrap')}}
Default values for UUID fields internally stored as Utf8 cannot be cast to UUID.
AFAIU the problem comes from the fact that in OSGi environment classes
{{org.apache.avro.util.Utf8}} and {{java.util.UUID}} are loaded by separate
classloaders thus simple class casting cannot be done.
To bypass the problem I changed
{code:java}
record.orderStatus = fieldSetFlags()[3] ? this.orderStatus : (java.util.UUID)
defaultValue(fields()[3]);
{code}
to
{code:java}
record.orderStatus = fieldSetFlags()[3] ? this.orderStatus :
java.util.UUID.fromString(defaultValue(fields()[3]).toString());
{code}
but I think maybe that could be done during class generation?
--
This message was sent by Atlassian Jira
(v8.3.4#803005)