user1926409
user1926409

Reputation: 23

google's protocol buffer from c# to java - Protocol message tag had invalid wire type

I am creating a stream in C# and trying to read it in java, but I receive the error: "Protocol message tag had invalid wire type." when i read it in my java code the object created in c#.

Details: I started from an equal .proto file (see below) to create the correspondent .java file and .cs file (compiling using the protoc for java in version "protobuf-2.4.1" and the protobuf-csharp-port-2.4.1.473-full-binaries for c#). I succeed to create the addressbook.java and the addressbook.cs.

The object is created in c# and written to a file using the following c# code:

[...]
byte[] bytes;

        //Create a builder to start building a message
        Person.Builder newContact = Person.CreateBuilder();

        //Set the primitive properties
        newContact.SetId(1)
                  .SetName("Foo")
                  .SetEmail("foo@bar");

        //Now add an item to a list (repeating) field
        newContact.AddPhone(
            //Create the child message inline
            Person.Types.PhoneNumber.CreateBuilder().SetNumber("555-1212").Build()
            );

        //Now build the final message:
        Person person = newContact.Build();


        newContact = null;
        using(MemoryStream stream = new MemoryStream())
        {
            //Save the person to a stream
            person.WriteTo(stream);
            bytes = stream.ToArray();


            //save this to a file (by me)
            ByteArrayToFile("personStreamFromC#", bytes);
[...]

I copy the created file "personStreamFromC#" to my java solution and try to read it using the following java code:

 AddressBook.Builder addressBook = AddressBook.newBuilder();

// Read the existing address book.
try {
    FileInputStream input = new FileInputStream(args[0]);
    byte[] data = IOUtils.toByteArray(input);
    addressBook.mergeFrom(data);
  // Read the existing address book.
  AddressBook addressBookToReadFrom =
          AddressBook.parseFrom(new FileInputStream(args[0]));
  Print(addressBookToReadFrom);
}

But I get the following message:

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.example.tutorial.AddressBookProtos$Person$Builder.mergeFrom(AddressBookProtos.java:1034) at com.example.tutorial.AddressBookProtos$Person$Builder.mergeFrom(AddressBookProtos.java:1) at com.google.protobuf.CodedInputStream.readMessage(CodedInputStream.java:275) at com.example.tutorial.AddressBookProtos$AddressBook$Builder.mergeFrom(AddressBookProtos.java:1715) at com.example.tutorial.AddressBookProtos$AddressBook$Builder.mergeFrom(AddressBookProtos.java:1) at com.google.protobuf.AbstractMessage$Builder.mergeFrom(AbstractMessage.java:300) at com.google.protobuf.AbstractMessage$Builder.mergeFrom(AbstractMessage.java:238) at com.google.protobuf.AbstractMessageLite$Builder.mergeFrom(AbstractMessageLite.java:162) at com.google.protobuf.AbstractMessage$Builder.mergeFrom(AbstractMessage.java:716) at com.google.protobuf.AbstractMessage$Builder.mergeFrom(AbstractMessage.java:238) at com.google.protobuf.AbstractMessageLite$Builder.mergeFrom(AbstractMessageLite.java:153) at com.google.protobuf.AbstractMessage$Builder.mergeFrom(AbstractMessage.java:709) at AddPerson.main(test.java:104)

Below the .proto file: package tutorial; message Person { required string name = 1; required int32 id = 2; // Unique ID number for this person. optional string email = 3;

 enum PhoneType {
   MOBILE = 0;
   HOME = 1;
   WORK = 2;
 }

 message PhoneNumber {
   required string number = 1;
  optional PhoneType type = 2 [default = HOME];
 }

 repeated PhoneNumber phone = 4;
 }

message AddressBook {
  repeated Person person = 1;
  }

Any ideas ??

Upvotes: 2

Views: 8086

Answers (2)

hoaz
hoaz

Reputation: 10163

You write Person object to file in C#, but then read AddressBook in Java, I don't think this is correct. Try following in your Java code:

Person.parseFrom(new FileInputStream(args[0]));

Upvotes: 2

Marc Gravell
Marc Gravell

Reputation: 1063013

One common mistake that can cause invalid wire-type errors (especially when using files) is: over-writing an existing file without truncating it. We can't see your ByteArrayToFile, but frankly File.WriteAllBytes may be an easier option. The problem is that if the new data is smaller than the original contents, any remaining extra bytes are essentially garbage.

My advice:

  • check if you can deserialize it in c#; if you can't, the error is certainly in the file handling
  • if it works in c#, check how you are getting the file to the java code: are you copying it around anywhere?
  • and check you are using binary (not text) processing at all stages

Upvotes: 1

Related Questions