web-dev-qa-db-ja.com

Protobufエラー:プロトコルメッセージタグのワイヤタイプが無効でした

Javaでメッセージを読み込もうとすると、次のエラーが発生します

_Exception in thread "main" com.google.protobuf.InvalidProtocolBufferException: Protocol message tag had invalid wire type.
    at com.google.protobuf.InvalidProtocolBufferException.invalidWireType(InvalidProtocolBufferException.Java:78)
    at com.google.protobuf.UnknownFieldSet$Builder.mergeFieldFrom(UnknownFieldSet.Java:498)
    at com.google.protobuf.GeneratedMessage$Builder.parseUnknownField(GeneratedMessage.Java:438)

FileInputStream fis = new FileInputStream("F:/Newfolder/sample_message.txt");
Nt nlc = Nt.parseFrom(fis);

if(nlc.hasMessageId())
{
    System.out.println("MessageId: "+nta2sse.getMessageId());
}
_

if(nlc.hasMessageId())で例外が発生しています


これが完全なスタックトレースです。

_Exception in thread "main" com.google.protobuf.InvalidProtocolBufferException: Protocol message tag had invalid wire type.
    at com.google.protobuf.InvalidProtocolBufferException.invalidWireType(InvalidProtocolBufferException.Java:78)
    at com.google.protobuf.UnknownFieldSet$Builder.mergeFieldFrom(UnknownFieldSet.Java:498)
    at com.google.protobuf.GeneratedMessage$Builder.parseUnknownField(GeneratedMessage.Java:438)
    at com.soeasy.aanta.nta.sse.NtaSse$Nta2Sse$Builder.mergeFrom(NtaSse.Java:523)
    at com.soeasy.aanta.nta.sse.NtaSse$Nta2Sse$Builder.mergeFrom(NtaSse.Java:1)
    at com.google.protobuf.AbstractMessage$Builder.mergeFrom(AbstractMessage.Java:1)
    at com.google.protobuf.AbstractMessageLite$Builder.mergeFrom(AbstractMessageLite.Java:212)
    at com.google.protobuf.AbstractMessage$Builder.mergeFrom(AbstractMessage.Java:746)
    at com.google.protobuf.AbstractMessage$Builder.mergeFrom(AbstractMessage.Java:1)
    at com.google.protobuf.AbstractMessageLite$Builder.mergeDelimitedFrom(AbstractMessageLite.Java:282)
    at com.google.protobuf.AbstractMessage$Builder.mergeDelimitedFrom(AbstractMessage.Java:760)
    at com.google.protobuf.AbstractMessageLite$Builder.mergeDelimitedFrom(AbstractMessageLite.Java:288)
    at com.google.protobuf.AbstractMessage$Builder.mergeDelimitedFrom(AbstractMessage.Java:752)
    at com.soeasy.aanta.nta.sse.NtaSse$Nta2Sse.parseDelimitedFrom(NtaSse.Java:338)
    at com.soeasy.aanta.nta.sse.NtaSseServer.main(NtaSseServer.Java:60)
_

サンプルの_message.txtには次のものがあります。

_message_id: 1
batch_meas_update {
  device_update {
    unique_device_id {
      device_type: ME
      device_id: 161
    }
    meas_update {
      override_status: OVERRIDE_INACTIVE
      bad_data_status: GOOD_DATA
      scada_status: SCADA_ACTIVE
      weight: 1.0
      value: 406.596
    }
  }
}
_

.protoファイルに準拠しています

ありがとう

9
javaMan

例外が発生しているのではないかと疑っています。parseFromで発生することを期待しています。最初の3行だけでなく、fullスタックトレースを投稿できますか?

基本的にファイルが壊れているのではないかと強く思います。 binaryファイルであるはずのファイルに.txt拡張子を付けたという事実は、いくぶん疑わしいです...ファイルは実際にはどのように見えますか?このようにparseFromを使用して、protobufメッセージのASCII表現を解析することはありません。

編集:コメントにリンクされている質問のとおり、binaryデータ用に設計されたメソッドを使用してtextファイルを解析しようとしています。

次のようなものを使用したい:

// Use the normal try/finally for closing reliably
InputStreamReader reader = new InputStreamReader(fis, "ASCII");

Nt.Builder builder = Nt.newBuilder();
TextFormat.merge(reader, builder);
Nt nt = builder.build();
18
Jon Skeet

ユーザーがこのタイプのメッセージを報告しているのを見ると、ほとんどの場合、ファイルが破損していることを意味します。プロトコルバッファはテキストエンコーディングで表すことができないバイナリ形式であるため、.txtで始まることは心配な兆候です(base-64などを数えない限り)。

これのもう1つの一般的な原因は、lessデータでファイルを上書きし、余分なデータをトリミングしないことです。プロトコルバッファには(ルートメッセージ用に)長さのプレフィックスもターミネータも含まれていないため、以前のファイルの内容からの余分なデータ(現在は本質的にガベージ)が処理されます。これは悪いことです。上書きするときは、常に出力をトリミングする必要があります。

2
Marc Gravell