Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Protobuf 2.5.0 bug?

I've migrated from google protobuf v. 2.4.1 to v. 2.5.0 (no other change).

I had a perfectly working client-server [android<>gae dev server] communication using 2.4.1.
Now with 2.5.0 it is broken.

Without any modification to the .proto file, I've setup my client and server with the new 2.5.0 jar, and with the new protoc executable I've generated a new source file for client and server from the same proto file.

Now I get this error on the server when I'm trying to parse the message:

VerifyError: class ... overrides final method getUnknownFields.()Lcom/google/protobuf/UnknownFieldSet;

full stack:

java.lang.VerifyError: class com.mta.pb.ACM$MyRequest overrides final method getUnknownFields.()Lcom/google/protobuf/UnknownFieldSet;
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:791)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at com.google.appengine.tools.development.IsolatedAppClassLoader.loadClass(IsolatedAppClassLoader.java:213)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:186)
at com.google.appengine.tools.development.agent.runtime.RuntimeHelper.checkRestricted(RuntimeHelper.java:70)
at com.google.appengine.tools.development.agent.runtime.Runtime.checkRestricted(Runtime.java:64)
**at com.mta.server.p.AndroidServletP.doPost(AndroidServletP.java:91)** <- my code
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
at com.googlecode.objectify.cache.AsyncCacheFilter.doFilter(AsyncCacheFilter.java:57)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.api.socket.dev.DevSocketFilter.doFilter(DevSocketFilter.java:74)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    ...etc

Things I've already tried:

1) Reading the changelog, I've tried to change the parse code from:

            request = MyRequest.parseFrom(requstBlob); 

to

            request = MyRequest.PARSER.parseFrom(requstBlob); 

(this is the same line 91 that you see in the stack trace).
It didn't change a thing. Same error.

2) I've tried to parse the message manually:
I printed out the base64 string coming to the server, converted it into binary

base64 -d in64 > out64.bin

than

protoc --decode=MyRequest my.proto < out64.bin > tmp.txt

And it parses it perfectly. So the problem is only at the parsing part of the new protobuf.

3) I've tried taking ReqType out of MyRequest, no effect.

For reference: the relevant protobuf definition

/**
 * Master request object
 */
message MyRequest {
    optional RequestContext context = 1;
    optional MyReport myReport = 2;
    optional CategoryRequest catRequest = 3;
    optional GetMessage getMessage = 4;
    optional SearchRequest searchRequest = 5;
    enum ReqType {
        UNDEFINED = 1;
        REGISTER = 104;
        UPDATE = 123;
        GET_PAYLOAD = 100;
        SEARCH = 200;
        REPEAT_GCM = 623;
        REPEAT_PREPARE = 842;
    }
    optional ReqType reqType = 10;
    optional bool repeat = 11;
}

Any advice will be greatly appreciated!

like image 357
Amir Uval Avatar asked Dec 27 '22 05:12

Amir Uval


1 Answers

I would guess you did not upgrade / recompile something. In protobuf 2.4.1 version in the jars.

in the GeneratedMessage class, getUnknownFields was a final method in 2.4.1 but in 2.5.0 it becomes:

  //@Override (Java 1.6 override semantics, but we must support 1.5)
  public UnknownFieldSet getUnknownFields() {
    throw new UnsupportedOperationException(
        "This is supposed to be overridden by subclasses.");
  }

and is overridden in the generated class. You may need to recompile all your classes that use generated protocol buffer classes.

Given the messages

java.lang.VerifyError: class com.mta.pb.ACM$MyRequest overrides final method getUnknownFields.()Lcom/google/protobuf/UnknownFieldSet;

This tells you you are running code generated with Protocol-Buffers 2.5.0 with a protocol-fuffers-2.4.1 (or earlier) jar.

like image 102
Bruce Martin Avatar answered Jan 04 '23 03:01

Bruce Martin