Search code examples
javajunitprotocol-buffersprotoc

Proto Generated class's toString causing Exception


I'm following Google's tutorial [ https://developers.google.com/protocol-buffers/docs/javatutorial?hl=en ] to write a Proto Class.

My Proto file is

package protoc_Shashi;

option java_package="com.shashi.protoc.generated";
option java_outer_classname="AddressBookProtos";

message Person {
    required string name = 1;
    required int32 id = 2;
    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 number = 4;
}

message AddressBook {
    repeated Person person = 1;
}

and i was writing a junit test case to create a new Person object as specified in the tutorial.
Object is created but calling it's toString() method gives me an error that it's supposed to be overrriden by subclasses. Stacetrace for the same is as follows

java.lang.UnsupportedOperationException: This is supposed to be overridden by subclasses.
    at com.google.protobuf.GeneratedMessage.getUnknownFields(GeneratedMessage.java:192)
    at com.google.protobuf.TextFormat$Printer.print(TextFormat.java:301)
    at com.google.protobuf.TextFormat$Printer.printFieldValue(TextFormat.java:434)
    at com.google.protobuf.TextFormat$Printer.printSingleField(TextFormat.java:353)
    at com.google.protobuf.TextFormat$Printer.printField(TextFormat.java:309)
    at com.google.protobuf.TextFormat$Printer.print(TextFormat.java:299)
    at com.google.protobuf.TextFormat$Printer.access$400(TextFormat.java:273)
    at com.google.protobuf.TextFormat.print(TextFormat.java:76)
    at com.google.protobuf.TextFormat.printToString(TextFormat.java:143)
    at com.google.protobuf.AbstractMessage.toString(AbstractMessage.java:79)
    at com.shashi.protoc.generated.AddressBookProtosTest.createPerson(AddressBookProtosTest.java:29)

My junit test class is as follows

package com.shashi.protoc.generated;

import org.junit.Test;

/**
 * @author Shashi Bhushan
 *         Created on 29/12/15.
 *         For Google-Protoc
 */
public class AddressBookProtosTest {

    @Test
    public void createPerson(){
        AddressBookProtos.Person person =
                AddressBookProtos.Person.newBuilder()
                .setId(100)
                .setName("Shashi")
                .setEmail("sb@sb.com")
                .addNumber(
                        AddressBookProtos.Person.PhoneNumber.newBuilder()
                                .setNumber("555")
                                .setType(AddressBookProtos.Person.PhoneType.WORK)
                )
                .build();

        System.out.println("Is Initialized : " +
                person.isInitialized());
        System.out.println("To String : " +
                person.toString());     // Error on this line
    }
}

am i missing something trivial here ?


Solution

  • Make sure that your protoc and your libprotobuf.jar are exactly the same version. From the stack trace you give, my guess is that you're using protoc v3 and libprotobuf.jar v2.x, although I'm not certain. In general, you always have to use exactly the same versions of these two things because protoc generates code that depends on private APIs in libprotobuf.jar which often change between versions.