我有一个使用Google Protocol Buffers的项目。一旦我尝试使用ProGuard对其进行模糊处理,似乎protobuf会导致问题。
我将自己的所有课程打包到mybuildedclasses.jar
。 Google代码打包成protbuf.jar
mybuildedclasses.jar
protobuf.jar
other external jars
之后我试图混淆mybuildedclasses.jar
。配置文件类似于此one。最终所有的罐子都装在另一个胖罐子里。
我运行程序,一旦尝试发送消息,就会打印出这种异常。
Caused by: java.lang.RuntimeException: Generated message class "org.mypackage.messages.Control$MessageControlHandCard$Builder" missing method "getCardId".
at com.google.protobuf.GeneratedMessage.getMethodOrDie(GeneratedMessage.
java:1366)
at com.google.protobuf.GeneratedMessage.access$1(GeneratedMessage.java:1
361)
at com.google.protobuf.GeneratedMessage$FieldAccessorTable$SingularField
Accessor.<init>(GeneratedMessage.java:1502)
at com.google.protobuf.GeneratedMessage$FieldAccessorTable.<init>(Genera
tedMessage.java:1441)
at org.mypackage.Control$1.assignDescriptors(SourceFile:32
20)
at com.google.protobuf.Descriptors$FileDescriptor.internalBuildGenerated
FileFrom(Descriptors.java:300)
at org.evogame.common.messages.Control.<clinit>(SourceFile:3278)
... 60 more
Caused by: java.lang.NoSuchMethodException: org.evogame.common.messages.Control$
MessageControlHandCard$Builder.getCardId()
at java.lang.Class.getMethod(Class.java:1622)
at com.google.protobuf.GeneratedMessage.getMethodOrDie(GeneratedMessage.
java:1364)
并且
Exception in thread "AWT-EventQueue-0" java.lang.ExceptionInInitializerError
at org.mypackage.messages.Control$MessageControlGameRequest.interna
lGetFieldAccessorTable(SourceFile:527)
at com.google.protobuf.GeneratedMessage.getAllFieldsMutable(GeneratedMes
sage.java:105)
at com.google.protobuf.GeneratedMessage.getAllFields(GeneratedMessage.ja
va:153)
at com.google.protobuf.TextFormat$Printer.print(TextFormat.java:229)
at com.google.protobuf.TextFormat$Printer.access$2(TextFormat.java:226)
at com.google.protobuf.TextFormat.print(TextFormat.java:69)
at com.google.protobuf.TextFormat.printToString(TextFormat.java:116)
at com.google.protobuf.AbstractMessage.toString(AbstractMessage.java:87)
如果我不混淆,那么一切都很完美。 那么应该如何为Google Protocol Buffers相关代码特别配置-keep
选项?
我已经尝试过生成的消息文件,但它也提供了相同的例外。
-keep public class org.mypackage.messages.* {
}
答案 0 :(得分:7)
看起来这可能仅仅是包裹未对齐的问题。看看错误:
Caused by: java.lang.RuntimeException: Generated message class
"org.mypackage.Control$MessageControlHandCard$Builder"
missing method "getCardId".
...
那就是org.mypackage.Control
。
现在看看你的Proguard配置:
-keep public class org.mypackage.messages.* {
}
这是使用org.mypackage.messages
,不包括org.mypackage.Control
。
现在可能那些不是你的真正的包名 - 但如果它们具有代表性,听起来你需要更改你的.proto
文件来发送包中的类{{ 1}}而不是org.mypackage.messages
。 (你可以改变你的Proguard配置,但听起来会觉得太多了。)
或者,您可以只使用继承树。我自己不是Proguard用户,但根据examples判断,您可能需要:
org.mypackage
我希望无论封装是什么,都可以处理所有协议缓冲区类。您可能发现protobuf在“顶级”课程中还有其他字段/方法。
编辑:进一步查看文档,可能需要:
-keep public class * extends com.google.protobuf.GeneratedMessage
保留所有成员。还有其他“保留”选项正在查看而不是-keep public class * extends com.google.protobuf.GeneratedMessage { *; }
,例如-keep
。
答案 1 :(得分:0)
我更喜欢指定字段名称而不是保留整个类成员,这会产生更小的输出。
-keepclassmembers your.class.name {
int sampleIntField;
String sampleStringField;
}