2012-12-31 6 views
3

Google 프로토콜 버퍼가 사용되는 프로젝트가 있습니다. ProGuard로 난독 화하려고하면 protobuf가 문제를 일으키는 것 같습니다.프로토콜 버퍼가있는 프로젝트에서 Proguard를 사용하는 기능은 무엇입니까?

내 모든 클래스는 mybuildedclasses.jar에 패키지되어 있습니다. 구글 코드는 내가 mybuildedclasses.jar를 당황하게하려고 그 후 protbuf.jar

mybuildedclasses.jar 
protobuf.jar 
other external jars 

로 패키지됩니다. 구성 파일은 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 프로토콜 버퍼 관련 코드에 대해 -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와 구성을 보면 : org.mypackage.Control을 포함하지 것이다, org.mypackage.messages을 사용하고 그

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

.

지금 아마도 사람들은 당신의 실제 패키지 이름없는 -하지만이 대표 인 경우 패키지 대신 org.mypackageorg.mypackage.messages 수업을 방출하기 위해 .proto 파일을 변경해야처럼 들린다. (대신 Proguard 설정을 바꿀 수는 있지만 너무 많이 선택하는 것처럼 들립니다.)

또는 상속 트리를 사용할 수도 있습니다. 나는 Proguard와 사용자 자신 아니에요,하지만 examples에 의해 판단, 당신은 할 수 있습니다 :

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

내가 그 관계없이 패키지의 모든 프로토콜 버퍼 클래스에서 작동하도록 기대. protobuf가 "최상위"클래스에서 기대하는 다른 필드/메소드가 있음을 알 수 있습니다.

편집 :

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

뿐만 아니라 모든 회원을 유지하기 위해 : 더 문서를 보면, 그것은 당신이 필요로 할 수있다. -keepnames과 같이 -keep 대신 보이는 다른 "보관"옵션이 있습니다.

+0

첫 번째 답변을 보내 주셔서 감사합니다. '이것은 패키지가 잘못 정렬되는 문제 일 수 있습니다. '- 실제 패키지 이름을 수동으로 변경하여 여기에 올리는 것은 오타라고 생각합니다. 나는 그 질문을 편집했다. –

+0

'-keep public class * extends com.google.protobuf.GeneratedMessage' 나는 그것을 시도 할 필요가있다. 비록 그것이 클래스의 이름이나 그 안에있는 모든 메소드와 필드의 이름 만 지킬 것인지에 대해서는 완전히 이해하지 못했습니다. –

+0

@NikolayKuznetsov : 생각하시오, 아니면 확인하셨습니까? 이것은 * exact * 오류 메시지와 * 정확한 * Proguard 구성 라인을 바꾸지 않고 입력 할 가치가있는 곳입니다 ... 질문에서 두 번째 예외는 동일한 문제를 가지고 있습니다 ... –

0

훨씬 작은 출력을 생성하는 전체 클래스 멤버를 유지하는 대신 필드 이름을 지정하는 것을 선호합니다.

-keepclassmembers your.class.name { 
    int sampleIntField; 
    String sampleStringField; 
} 
관련 문제