2012-12-31 71 views
3

我有一個使用Google Protocol Buffers的項目。一旦我嘗試用ProGuard對其進行混淆,似乎protobuf會導致問題。在Protocol Buffers項目中使用Proguard有什麼特點?

所有我自己的類我包裝成mybuildedclasses.jar。谷歌代碼打包成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.* { 
} 
+0

您是否設法解決這個問題?如果是,請分享你的發現?我很長一段時間都陷入了同樣的問題。 – Atul

回答

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文件發出的包org.mypackage.messages而不是org.mypackage類。 (你可以改變你Proguard的配置,而不是,但它聽起來就像是會拿起太多。)

或者,你也許能夠只使用繼承樹。我不是一個Proguard的用戶自己的,而是由examples來看,你可能會想:

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

我期望在您的所有協議緩衝區類,無論包裝工作。你可能發現protobuf期望在「頂級」類中有其他字段/方法。

編輯:在文檔進一步看,這可能是因爲你需要:

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

維護所有成員。還有其他的「保持」選項,而不是-keep,比如-keepnames

+0

感謝您的第一個答案。 「這可能只是包裹錯位的問題」 - 我認爲這只是一個手動重命名我的真實包名在這裏發佈的錯字。我編輯了這個問題。 –

+0

'-keep public class * extends com.google.protobuf.GeneratedMessage'我需要嘗試一下。雖然我不完全瞭解它是否只保留類的名稱,或者其中的每個方法和字段的名稱。 –

+0

@NikolayKuznetsov:你認爲,或者你已經驗證?這是值得把*精確*錯誤消息和*精確* Proguard配置行,而不會改變它們......值得注意的是,在你的問題中的第二個異常有同樣的問題... –

0

我更喜歡指定字段名稱而不是保留整個類成員,這會產生更小的輸出。

-keepclassmembers your.class.name { 
    int sampleIntField; 
    String sampleStringField; 
} 
相關問題