What are features of using Proguard in project with Protocol Buffers?

风流意气都作罢 提交于 2019-12-07 16:26:50

问题


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.

All my own classes I package into mybuildedclasses.jar. Google code is packaged into protbuf.jar

mybuildedclasses.jar
protobuf.jar
other external jars

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)

And

 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)

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.* {
 }

回答1:


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".
 ...

So that's org.mypackage.Control.

Now look at your Proguard configuration:

-keep public class org.mypackage.messages.* {
}

That's using org.mypackage.messages, which wouldn't include org.mypackage.Control.

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.)

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

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.

EDIT: Looking at the documentation further, it may be that you need:

-keep public class * extends com.google.protobuf.GeneratedMessage { *; }

to preserve all members as well. There are other "keep" options which are looking at instead of -keep, such as -keepnames.




回答2:


I prefer specifying the field name instead of keeping whole class members, which producing much smaller output.

-keepclassmembers your.class.name {
  int sampleIntField;
  String sampleStringField;
}


来源:https://stackoverflow.com/questions/14098225/what-are-features-of-using-proguard-in-project-with-protocol-buffers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!