我已经从google protobuf v.2.4.1迁移到v.2.5.0(没有其他更改)。
我使用2.4.1进行了完美的客户端 - 服务器[android<> gae dev服务器]通信。
现在有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)我尝试从MyRequest中取出ReqType,没效果。
供参考:相关的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;
}
任何建议都将不胜感激!
答案 0 :(得分:7)
我猜你没有升级/重新编译。在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-fuffers-2.4.1(或更早版本)jar 的Protocol-Buffers 2.5.0运行代码生成。
答案 1 :(得分:1)
当我在升级到2.5后编译应用程序时,发生了类似的事情。最终我意识到旧的2.4 jar仍然和新的2.5 jar一样在文件夹中,并且构建系统xml文件仍然指的是旧的。这只是一个更小心的问题 - 没有什么神秘的事情发生。