4

我已经从 google protobuf v. 2.4.1 迁移到 v. 2.5.0(没有其他变化)。

我使用 2.4.1 进行了完美的客户端-服务器 [android<>gae dev server] 通信。
现在有了 2.5.0,它就坏了。

在没有对 .proto 文件进行任何修改的情况下,我使用新的 2.5.0 jar 设置了我的客户端和服务器,并且使用新的 protoc 可执行文件,我从同一个 proto 文件为客户端和服务器生成了一个新的源文件。

现在,当我尝试解析消息时,我在服务器上收到此错误:

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)阅读更改日志,我试图从以下位置更改解析代码:

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

任何建议将不胜感激!

4

2 回答 2

8

我猜你没有升级/重新编译一些东西。在罐子里的 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;

这告诉您正在运行使用 Protocol-Buffers 2.5.0 和protocol-fuffers-2.4.1(或更早版本)jar生成的代码。

于 2013-04-22T12:21:35.753 回答
2

A similar thing happened to me when I was compiling an application after upgrading to 2.5. Eventually I realized that the old 2.4 jar was still in the same folder as the new 2.5 jar, and that the build system xml file was still referring to the old one. It was just a matter of being a little more careful - nothing mysterious was going on.

于 2014-06-10T18:49:38.720 回答