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)

Reply via email to