2

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 ??

2
  • 2
    you write Person object to file in C#, but then read AddressBook in Java, i don't think this is correct. try Person.parseFrom(new FileInputStream(args[0])); Commented Dec 24, 2012 at 10:25
  • 1
    @hoaz you should add that as an answer Commented Dec 24, 2012 at 12:44

2 Answers 2

2

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]));
Sign up to request clarification or add additional context in comments.

Comments

1

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

2 Comments

1) Using the File.WriteAllBytes didn't help, still same exception appearing in Java 2) Deserialization in c# works perfectly - see below: 3) I copy the file with a simple copy-paste from the bin directory in C# to the bin in Java.. should I do it differently ?
@MarcGravell this helped me a lot with a similar problem! Thank you for the advice!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.