[prev in list] [next in list] [prev in thread] [next in thread]
List: avro-dev
Subject: [jira] [Created] (AVRO-2780) Protobuf definition with outer class causes stack overflow for Protobuf
From: "Tianyu Lang (Jira)" <jira () apache ! org>
Date: 2020-03-24 23:55:00
Message-ID: JIRA.13293676.1585094073000.120819.1585094100263 () Atlassian ! JIRA
[Download RAW message or body]
Tianyu Lang created AVRO-2780:
---------------------------------
Summary: Protobuf definition with outer class causes stack overflow for \
ProtobufDatumReader Key: AVRO-2780
URL: https://issues.apache.org/jira/browse/AVRO-2780
Project: Apache Avro
Issue Type: Bug
Components: java
Affects Versions: 1.9.2
Reporter: Tianyu Lang
We have found a bug with ProtobufDatumReader. In Protobuf, if the ".proto" file has \
the same name as the message, in the generated ".java" file, "OuterClass" will be \
appended to the outer class's name. This is documented here: \
[https://developers.google.com/protocol-buffers/docs/reference/java-generated#invocation]
Now we have a test protobuf class defined like so:
{code:java}
syntax = "proto2";
package test.avrobug;
option java_package = "com.test.protos.avrobug";
option java_generic_services = true;
enum State {
BAD = 0;
VERY_BAD = 1;
SUPER_BAD = 2;
}
message Dummy {
optional string token = 1;
optional string description = 2;
optional int64 count = 3;
optional State state = 4;
}
{code}
If we first create a Protobuf object, write it to a file as Avro through \
ProtobufDatumReader, then read it into a Protobuf with ProtobufDatumReader, a stack \
overflow exception will happen. Code to reproduce is as follows:
{code:java}
@Test
public void ProtoToAvroOuterClassBug() throws Exception {
DummyOuterClass.Dummy dummy = DummyOuterClass.Dummy.newBuilder()
.setCount(50)
.setDescription("hehe")
.setToken("abc123")
.setState(DummyOuterClass.State.BAD)
.build();
ProtobufDatumWriter<DummyOuterClass.Dummy> pbWriter =
new ProtobufDatumWriter<>(DummyOuterClass.Dummy.class);
DataFileWriter<DummyOuterClass.Dummy> dataFileWriter = new \
DataFileWriter<>(pbWriter); Schema schema = \
ProtobufData.get().getSchema(DummyOuterClass.Dummy.class); \
dataFileWriter.create(schema, new \
File("/Users/tianyu/Documents/DummyAvroNoDefaultValues.avro")); \
dataFileWriter.append(dummy); dataFileWriter.close();
ProtobufDatumReader<DummyOuterClass.Dummy> pbReader =
new ProtobufDatumReader<>(DummyOuterClass.Dummy.class);
DataFileReader<DummyOuterClass.Dummy> dataFileReader =
new DataFileReader<>(new \
File("/Users/tianyu/Documents/DummyAvroNoDefaultValues.avro"), pbReader);
while(dataFileReader.hasNext()) {
DummyOuterClass.Dummy record = dataFileReader.next();
String recordStr = record.toString();
String originStr = dummy.toString();
System.out.println(recordStr);
System.out.println(originStr);
}
}
{code}
When this is run, a stack overflow exception will happen with the following stack \
trace:
{code:java}
java.lang.StackOverflowErrorjava.lang.StackOverflowError \
at java.base/java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936) \
at org.apache.avro.specific.SpecificData.getClass(SpecificData.java:250) \
at org.apache.avro.protobuf.ProtobufData.newRecord(ProtobufData.java:141) \
at org.apache.avro.protobuf.ProtobufData.newRecord(ProtobufData.java:143) \
at org.apache.avro.protobuf.ProtobufData.newRecord(ProtobufData.java:143) \
at
..................{code}
newRecord() is recursed infinitely until stack explodes
I did a bit code tracing and I found out when Avro tries to load the corresponding \
Java class from the schema, it tries to load the class \
"com.squareup.protos.cardr.Dummy.Dummy". I suspect the double "Dummy" at the end is \
related to the stack overflow, but I don't have enough knowledge on Proto or Avro to \
know the exact reason.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic