Uploaded image for project: 'Apache Avro'
  1. Apache Avro
  2. AVRO-2902

ClassCastException in generated Java classes when used in OSGi

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Minor
    • Resolution: Unresolved
    • 1.9.2
    • None
    • None
    • Karaf 4.2.8, 4.2.9

    Description

      Example schema:

      {
        "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" }
      	        ]
      }
      

       

      Generated by avro-maven-plugin POJO fragment:

      ...
      @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
      ...
      

       

      Example code causing exception:

      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());
          }
      
      

       

      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

      record.orderStatus = fieldSetFlags()[3] ? this.orderStatus : (java.util.UUID) defaultValue(fields()[3]);
      

      to

      record.orderStatus = fieldSetFlags()[3] ? this.orderStatus : java.util.UUID.fromString(defaultValue(fields()[3]).toString());
      

      but I think maybe that could be done during class generation?

       

       

      Attachments

        Activity

          People

            Unassigned Unassigned
            scream Ivan A. Malich
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated: