6

Google Protocol Buffers が使用されているプロジェクトがあります。ProGuard で難読化しようとすると、protobuf が問題を引き起こしているようです。

にパッケージ化するすべての独自のクラスmybuildedclasses.jar。Googleコードはにパッケージ化されていますprotbuf.jar

mybuildedclasses.jar
protobuf.jar
other external jars

その後、難読化しようとしていますmybuildedclasses.jar。構成ファイルはこれに似ています。最終的に、すべての jar は別の太い 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)

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

2 に答える 2

11

これは、パッケージの位置がずれているだけの問題のようです。エラーを見てください:

 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ファイルを変更して、パッケージ内のクラスorg.mypackage.messagesorg.mypackage. (代わりに Proguard 構成を変更することもできますが、それではあまりにも多くのことが拾われてしまうようです。)

または、継承ツリーを使用することもできます。私自身は Proguard ユーザーではありませんが、から判断すると、次のことが必要になる場合があります。

-keep public class * extends com.google.protobuf.GeneratedMessage

パッケージに関係なく、すべてのプロトコル バッファ クラスで動作することを期待しています。ただし、「トップレベル」クラスで protobuf が期待する他のフィールド/メソッドがあることに気付くかもしれません。

編集:ドキュメントをさらに見ると、次のものが必要になる場合があります。

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

また

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

すべてのメンバーも保持します。-keepの代わりにを見ている他の「キープ」オプションがあります-keepnames

于 2013-01-02T06:58:02.953 に答える
0

クラス メンバー全体を保持するのではなく、フィールド名を指定することを好みます。これにより、はるかに小さな出力が生成されます。

-keepclassmembers your.class.name {
  int sampleIntField;
  String sampleStringField;
}
于 2013-05-22T10:06:27.073 に答える