在带有协议缓冲区的项目中使用Proguard的功能是什么? [英] What are features of using Proguard in project with Protocol Buffers?
问题描述
我有一个使用Google协议缓冲区的项目.一旦我尝试使用ProGuard对其进行混淆,似乎protobuf会引起问题.
I have a project in where Google Protocol Buffers are used. Once I try to obfuscate it with ProGuard it seems that protobuf causes problem.
我打包到mybuildedclasses.jar
的所有我自己的类. Google代码打包到protbuf.jar
All my own classes I package into mybuildedclasses.jar
. Google code is packaged into protbuf.jar
mybuildedclasses.jar
protobuf.jar
other external jars
在那之后,我试图混淆mybuildedclasses.jar
.配置文件类似于一个.最终,所有罐子都包装在另一个胖罐子中.
After that I am trying to obfuscate mybuildedclasses.jar
. Config file is similar to this one. Eventually all jars are packaged inside another fat jar.
我运行程序,一旦尝试发送消息,就会打印出这种异常.
I run the program and once message is tried to be sent this kind of Exceptions are printed.
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协议缓冲区相关的代码的-keep
选项?
If I don't obfuscate then everything works perfectly. So how should particularly configure -keep
option for Google Protocol Buffers related code?
我尝试生成的消息文件,但是有相同的例外.
I have tried for generated message files, but it give same exceptions.
-keep public class org.mypackage.messages.* {
}
推荐答案
看起来这可能只是软件包未对齐的问题.查看错误:
It looks like this may just be a matter of the package being misaligned. Look at the error:
Caused by: java.lang.RuntimeException: Generated message class
"org.mypackage.Control$MessageControlHandCard$Builder"
missing method "getCardId".
...
所以是org.mypackage.Control
.
现在查看您的Proguard配置:
Now look at your Proguard configuration:
-keep public class org.mypackage.messages.* {
}
使用的是org.mypackage.messages
,其中不包括org.mypackage.Control
.
That's using org.mypackage.messages
, which wouldn't include org.mypackage.Control
.
现在大概这些不是您的 real 软件包名称-但是,如果它们具有代表性,听起来您需要更改您的.proto
文件,以发出软件包org.mypackage.messages
中的类org.mypackage
. (您可以改为更改Proguard的配置,但听起来会增加很多.)
Now presumably those aren't your real package names - but if they're representative, it sounds like you need to change your .proto
file to emit classes in the package org.mypackage.messages
instead of org.mypackage
. (You could change your Proguard configuration instead, but it sounds like that would pick up too much.)
或者,您也许可以只使用继承树.我自己不是Proguard用户,而是根据示例进行判断,您可能想要:
Alternatively, you might be able to just use the inheritance tree. I'm not a Proguard user myself, but judging by the examples, you might want:
-keep public class * extends com.google.protobuf.GeneratedMessage
我希望无论您使用哪种软件包,它都能在您所有的协议缓冲区类上工作.您可能会 发现protobuf希望在顶层"类中还有其他字段/方法.
I'd expect that to work on all your protocol buffer classes regardless of package. You may find that there are other fields/methods which protobuf expects in the "top level" class though.
进一步查看文档,可能是您需要:
Looking at the documentation further, it may be that you need:
-keep public class * extends com.google.protobuf.GeneratedMessage { *; }
或
-keep public class * extends com.google.protobuf.GeneratedMessageLite { *; }
也保留所有成员.还有其他代替"c3"而不是"ceep"的选项,例如-keepnames
.
to preserve all members as well. There are other "keep" options which are looking at instead of -keep
, such as -keepnames
.
这篇关于在带有协议缓冲区的项目中使用Proguard的功能是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!