Java中Protobuf转Avro报错:FileDescriptor无法转换为Descriptor
解决Avro ProtobufData.getSchema抛出ClassCastException的问题
问题重现
尝试通过Avro的ProtobufData从Protobuf生成的Java类获取Avro Schema时抛出类型转换异常:
ProtobufData model = ProtobufData.get(); Schema schema = model.getSchema(MyProto.class); // 此处抛出异常
异常信息:
java.lang.ClassCastException: class com.google.protobuf.Descriptors$FileDescriptor cannot be cast to class com.google.protobuf.Descriptors$Descriptor
查看ProtobufData.getSchema(Class)的实现可知,代码会调用目标类的getDescriptor()方法,并尝试将返回值强转为Descriptor,但你的MyProto.class返回的是FileDescriptor,导致转换失败。
原因分析
你传入的MyProto.class是整个.proto文件生成的外层容器类,而非其中定义的具体Message类。Protobuf的代码生成规则中:
- 外层容器类(如
MyProto)的getDescriptor()方法返回FileDescriptor,代表整个.proto文件的描述符 - 而.proto文件中定义的
message会生成内部类(如MyProto.MyMessage),这类Message类的getDescriptor()才会返回Descriptor,对应单个消息的描述符
Avro的ProtobufData.getSchema(Class)方法设计时,期望传入的是单个Message或Enum的类对象,而非整个文件的外层类。
解决方案
有两种可行的解决方式:
方式1:传入具体的Message类
直接使用.proto文件中定义的消息对应的Java类(通常是外层类的内部类):
ProtobufData model = ProtobufData.get(); // 替换为你实际的Message内部类 Schema schema = model.getSchema(MyProto.MyMessage.class);
方式2:直接基于FileDescriptor生成Schema
如果你需要为整个.proto文件生成对应的Avro Schema,可以直接调用ProtobufData.getSchema(FileDescriptor)的重载方法:
// 获取整个文件的FileDescriptor FileDescriptor fileDescriptor = MyProto.getDescriptor(); ProtobufData model = ProtobufData.get(); Schema schema = model.getSchema(fileDescriptor);
内容的提问来源于stack exchange,提问作者MrE
相关产品推荐
相关产品推荐

