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

时间:2012-12-31 06:21:33

标签: java obfuscation protocol-buffers proguard

我有一个使用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.* {
 }

2 个答案:

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