You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@avro.apache.org by "Stefan Burkard (Jira)" <ji...@apache.org> on 2023/11/20 09:32:00 UTC

[jira] [Commented] (AVRO-2902) ClassCastException in generated Java classes when used in OSGi

    [ https://issues.apache.org/jira/browse/AVRO-2902?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17787902#comment-17787902 ] 

Stefan Burkard commented on AVRO-2902:
--------------------------------------

I don't think this is OSGi specific. I have almost the same exception but in a SpringBoot consumer. 
{code:java}
Caused by: 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 'app'; java.util.UUID is in module java.base of loader 'bootstrap') {code}
The cause of the problem is a minor update of {{io.confluent:kafka-streams-avro-serde}} (which contains {{io.confluent:kafka-avro-serializer}} of the same version) in the consumer from 7.4.x to 7.5 while the producer still uses version 7.4.x

When I produce a message (that contains UUIDs), the consumer throws this deserialization exception.  

> 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
>            Priority: Minor
>
> 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.20.10#820010)