2.5.0 protobuf的错误?(Protobuf 2.5.0 bug?)

2019-08-31 16:11发布

我从谷歌的protobuf v 2.4.1迁移。到v。2.5.0(并无其他变动)。

我不得不使用2.4.1一个正常使用客户端 - 服务器[机器人<> GAE开发服务器]的通信。
现在,随着2.5.0断裂。

没有任何修饰的.proto文件,我设置我的客户端和服务器与新的2.5.0罐,并用新的protoc可执行我产生来自同一原型文件的客户端和服务器的新的源文件。

现在,我得到当我试图解析邮件的服务器上此错误:

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

全栈:

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

事情我已经尝试:

1)读的changelog,我试图从改变解析的代码:

            request = MyRequest.parseFrom(requstBlob); 

            request = MyRequest.PARSER.parseFrom(requstBlob); 

(这是同线91,你在堆栈跟踪看到)。
它并没有改变任何事情。 同样的错误。

2)我试图手动解析消息:
我打印出的base64串来给服务器,将其转换成二进制

base64 -d in64 > out64.bin

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

并将其解析它完美。 所以,问题是只在新的protobuf的解析部分。

3)我试着服用ReqType出MyRequest,没有效果的。

供参考:相关protobuf的定义

/**
 * 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;
}

任何意见将不胜感激!

Answer 1:

我猜你没有升级/重新编译的东西。 在protobuf的2.4.1版本诠释的罐子。

GeneratedMessage,getUnknownFields是一个最后的方法在2.4.1但在2.5.0它变为:

  //@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.");
  }

和在生成的类被覆盖。 您可能需要重新编译使用生成的协议缓冲区类所有类。

鉴于消息

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

这告诉您正在运行与协议-缓冲器2.5.0 生成具有协议fuffers-2.4.1(或更早)罐的代码。



Answer 2:

类似的事情发生在我身上时,我升级到2.5后编译应用程序。 最终,我意识到,老坛子2.4仍然是在同一文件夹作为新的2.5罐子,编译系统xml文件仍然指的是旧的。 这只是被稍微小心些的问题 - 没有什么神秘的事情。



文章来源: Protobuf 2.5.0 bug?