在带有协议缓冲区的项目中使用Proguard的功能是什么? [英] What are features of using Proguard in project with Protocol Buffers?

查看:159
本文介绍了在带有协议缓冲区的项目中使用Proguard的功能是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆