Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Namespace mapping causes ClassCastException upon deserialization #22

Open
kosii opened this issue Aug 17, 2016 · 1 comment
Open

Namespace mapping causes ClassCastException upon deserialization #22

kosii opened this issue Aug 17, 2016 · 1 comment

Comments

@kosii
Copy link

kosii commented Aug 17, 2016

When I try to serialize/deserialize an Avro structure using the SpecificDatumWriter/SpecificDatumReader classes, the deserialization throws a ClassCastException:

Exception in thread "main" java.lang.ClassCastException: org.apache.avro.generic.GenericData$Record cannot be cast to foo.scala.Status

I created a project to reproduce the error. Removing the namespace mapping from the build.sbt and change import foo.scala._ to import foo._ in Main.scala resolves the problem.

I also tried to work around the problem by instantiating the reader with a custom class-loader, but it doesn't seem to work (I started from the supposition that the error is coming from the class loader not being able to load the correct classes because of the namespace mapping, see also: AVRO-1620, AVRO-1240 for similar errors)

new SpecificDatumReader[Status](Status.SCHEMA$, Status.SCHEMA$, new SpecificData(new ClassLoader() {
    override def loadClass(s: String, b: Boolean): Class[_] = {
      if (s == "foo.Status")
        super.loadClass("foo.scala.Status", b)
      else
        super.loadClass(s, b)
    }
  }))
@julianpeeters
Copy link
Owner

Hi @kosii

You're a hero for providing a runnable example :) That class cast exception seems to be common in avro, since seeing a GenericRecord when using the Specific API usually means that the SpecificDatum has fallen through to a GenericDatum because some schemas don't match. In this case, I see that Status.SCHEMA$ has the old namespace, and the error is solved by manually changing it to the new namespace.

(But I'm not exactly clear on why the current custom namespace tests pass then. Maybe they use FileWriters/FileReaders instead of raw Encoders/Decoders, so there's an extra schema in the file that avro's able to work with?)

Regarding a fix for avrohugger, I think the first thing to try is to make sure that custom namespaces are being checked for and old namespaces replaced in the SCHEMA$ field, and if that works for your example as well as the existing ones, then I'd say we're good to go.

Regarding timeframe, I'm a little busy currently and my queue is out likely two weeks, so even if I got a PR for the work, I still won't be able to publish a new version for a while.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants