在使用Protocol Buffers的项目中使用Proguard有什么特点?

Nik*_*sov 3 java obfuscation proguard protocol-buffers

我有一个使用Google Protocol Buffers的项目.一旦我尝试使用ProGuard对其进行模糊处理,似乎protobuf会导致问题.

我打包的所有课程mybuildedclasses.jar.谷歌代码打包成protbuf.jar

mybuildedclasses.jar
protobuf.jar
other external jars
Run Code Online (Sandbox Code Playgroud)

在那之后我试图混淆mybuildedclasses.jar.配置文件与此类似一个.最终所有的罐子都装在另一个胖罐子里面.

我运行程序,一旦尝试发送消息,就会打印出这种异常.

 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)
Run Code Online (Sandbox Code Playgroud)

 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)
Run Code Online (Sandbox Code Playgroud)

如果我不混淆那么一切都很完美.那么应该如何特别配置-keepGoogle Protocol Buffers相关代码的选项呢?

我已尝试生成消息文件,但它提供相同的例外.

-keep public class org.mypackage.messages.* {
 }
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 7

看起来这可能仅仅是包裹未对齐的问题.看看错误:

 Caused by: java.lang.RuntimeException: Generated message class 
     "org.mypackage.Control$MessageControlHandCard$Builder" 
      missing method "getCardId".
 ...
Run Code Online (Sandbox Code Playgroud)

那就是org.mypackage.Control.

现在看看你的Proguard配置:

-keep public class org.mypackage.messages.* {
}
Run Code Online (Sandbox Code Playgroud)

这是使用org.mypackage.messages,不包括org.mypackage.Control.

现在大概那些不是你真正的包名 - 但如果它们具有代表性,听起来你需要更改.proto文件以在包中发出类org.mypackage.messages而不是org.mypackage.(你可以改变你的Proguard配置,但听起来会觉得太多了.)

或者,您可以只使用继承树.我自己不是Proguard用户,但从示例来看,您可能需要:

-keep public class * extends com.google.protobuf.GeneratedMessage
Run Code Online (Sandbox Code Playgroud)

无论封装如何,我都希望能够处理所有协议缓冲区类.您可能会发现protobuf在"顶级"类中还有其他字段/方法.

编辑:进一步查看文档,可能需要:

-keep public class * extends com.google.protobuf.GeneratedMessage { *; }
Run Code Online (Sandbox Code Playgroud)

保留所有成员.还有其他"保持"选项,而不是-keep,例如-keepnames.