作者:美好心灵66 | 来源:互联网 | 2023-01-06 13:26
我正在尝试动态解析Java中的给定.proto文件,以解码Protobuf编码的二进制文件。
我有以下解析方法,其中“ proto”字符串包含.proto文件的内容:
public static Descriptors.FileDescriptor parseProto (String proto) throws InvalidProtocolBufferException, Descriptors.DescriptorValidationException {
DescriptorProtos.FileDescriptorProto descriptorProto = DescriptorProtos.FileDescriptorProto.parseFrom(proto.getBytes());
return Descriptors.FileDescriptor.buildFrom(descriptorProto, null);
}
但是,执行时,先前的方法将引发消息“协议消息标签的电线类型无效”的异常。我使用了Google的示例.proto文件,因此我认为它是有效的:https : //github.com/google/protobuf/blob/master/examples/addressbook.proto
这是堆栈跟踪:
15:43:24.707 [pool-1-thread-1] ERROR com.github.whiver.nifi.processor.ProtobufDecoderProcessor - ProtobufDecoderProcessor[id=42c8ab94-2d8a-491b-bd99-b4451d127ae0] Protocol message tag had invalid wire type.
com.google.protobuf.InvalidProtocolBufferException$InvalidWireTypeException: Protocol message tag had invalid wire type.
at com.google.protobuf.InvalidProtocolBufferException.invalidWireType(InvalidProtocolBufferException.java:115)
at com.google.protobuf.UnknownFieldSet$Builder.mergeFieldFrom(UnknownFieldSet.java:551)
at com.google.protobuf.GeneratedMessageV3.parseUnknownField(GeneratedMessageV3.java:293)
at com.google.protobuf.DescriptorProtos$FileDescriptorSet.(DescriptorProtos.java:88)
at com.google.protobuf.DescriptorProtos$FileDescriptorSet.(DescriptorProtos.java:53)
at com.google.protobuf.DescriptorProtos$FileDescriptorSet$1.parsePartialFrom(DescriptorProtos.java:773)
at com.google.protobuf.DescriptorProtos$FileDescriptorSet$1.parsePartialFrom(DescriptorProtos.java:768)
at com.google.protobuf.AbstractParser.parsePartialFrom(AbstractParser.java:163)
at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:197)
at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:209)
at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:214)
at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:49)
at com.google.protobuf.DescriptorProtos$FileDescriptorSet.parseFrom(DescriptorProtos.java:260)
at com.github.whiver.nifi.parser.SchemaParser.parseProto(SchemaParser.java:9)
at com.github.whiver.nifi.processor.ProtobufDecoderProcessor.lambda$onTrigger$0(ProtobufDecoderProcessor.java:103)
at org.apache.nifi.util.MockProcessSession.write(MockProcessSession.java:895)
at org.apache.nifi.util.MockProcessSession.write(MockProcessSession.java:62)
at com.github.whiver.nifi.processor.ProtobufDecoderProcessor.onTrigger(ProtobufDecoderProcessor.java:100)
at org.apache.nifi.processor.AbstractProcessor.onTrigger(AbstractProcessor.java:27)
at org.apache.nifi.util.StandardProcessorTestRunner$RunProcessor.call(StandardProcessorTestRunner.java:251)
at org.apache.nifi.util.StandardProcessorTestRunner$RunProcessor.call(StandardProcessorTestRunner.java:245)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
任何的想法?谢谢!
1> Marc Gravell..:
看来您正在尝试使用FileDescriptorProto.parseFrom
填充FileDescriptorProto
。这只会如果您提供的字节工作是二进制protobuf的内容-这是说:一个编译架构。您可以通过使用带有该选项的命令行工具来获得编译模式。你实际上传递它现在是文本字节组成的文本模式,这是没有什么希望。protoc
--descriptor_set_out
parseFrom
如果没有编译模式,则需要运行时.proto解析器。我不知道一个Java语言。protobuf-net包含一个(protobuf-net.Reflection),但它是C#/。NET。如果没有可用的运行时.proto解析器,则需要shell执行protoc
。
@WSH可能没有Java实现。协议编译器比您预期的要复杂得多,并且以多种语言维护编译器的多种实现没有多大意义。您应该尝试做的是安排使用--descriptor_set_out * offline *解析.protos,然后根据需要发送已编译的描述符集,而不是尝试按需解析整个.proto文件。