[
https://issues.apache.org/jira/browse/AVRO-1703?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15287597#comment-15287597
]
Trent Altman commented on AVRO-1703:
------------------------------------
Sure, let me give you some more detail.
I've been using https://github.com/julianpeeters/avrohugger for SpecificRecord
generation of Scala case classes from avro schemas. These generated case
classes extend SpecificRecordBase, so normally things work great. However, the
times when a schema must be inferred from the class through reflection tend to
break b/c of the error mentioned in the issue. This happens for things that
call the avro-mapred from Scala e.g. spark-avro.
The reason being Scala doesn't support a way to define a public static field on
a class. Scala only provides a straightforward way to have a field on a
singleton instance of that class. Since avro uses getDeclaredField() to find
the SCHEMA$ attribute on the SpecificRecord, this make scala interop difficult.
getDeclaredField() doesn't grab inherited fields, so I can't just define a java
class with the SCHEMA$ and extend it from my Scala case class. This is what led
to the patch of just looking for a SCHEMA$ method before looking for a SCHEMA$
field to allow Scala interop. The other solution would be to make the avro
reflection look at parent classes for the SCHEMA$ field instead of just called
getDeclaredField().
If you can point me to a way to use IndexedRecord that works, I'm happy to try
that. I would much prefer to patch avrohugger's code generation than to patch
avro directly.
This same lack of static field issue has caused problems with Java interop
previously in things like Android. Note
https://gist.github.com/lrytz/80f3141de8240f9629da
> Specific record should not only be determined by presence of SCHEMA$ field
> --------------------------------------------------------------------------
>
> Key: AVRO-1703
> URL: https://issues.apache.org/jira/browse/AVRO-1703
> Project: Avro
> Issue Type: Improvement
> Reporter: Marius Soutier
> Labels: starter
>
> I want to use Avro from Scala, i.e. generate case classes from an Avro
> schema. So far this is working fine except for one thing - fields in Scala
> classes are always private. This doesn't work with Avro SpecificRecords (at
> least when inferring the schema from the class) and results in the following
> exception:
> org.apache.avro.AvroRuntimeException: java.lang.IllegalAccessException: Class
> org.apache.avro.specific.SpecificData can not access a member of class
> <my.Class> with modifiers "private"
> The exception is thrown from the following line in
> org.apache.avro.specific.SpecificData:
> schema = (Schema)(c.getDeclaredField("SCHEMA$").get(null));
> My suggestion would be to additionally check for a method called `getSchema`
> and read the schema from that method.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)