[
https://issues.apache.org/jira/browse/AVRO-2902?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Ivan A. Malich updated AVRO-2902:
---------------------------------
Description:
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?
was:
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?
> 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.3.4#803005)