带有@Inject注释的ProGuard和RoboGuice问题

时间:2011-04-07 14:03:00

标签: android annotations guice proguard roboguice

在优化我的Android应用程序时,我遇到了一些proguard问题。似乎对注释类(@ com.google.inject.Inject)做了一些事情,Dalvik / Harmony在运行时不满意。

  

java.lang.annotation.IncompleteAnnotationException:   可选元素不完整   用于注释   com.google.inject.Inject

com.google.inject.Inject看起来像这样(Guice的一部分):

@Target(value={ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD})
@Retention(value=java.lang.annotation.RetentionPolicy.RUNTIME)
@Documented
public abstract @interface com.google.inject.Inject extends Annotation {
  public abstract boolean optional() default false;
}

这是发布失败的原因:

04-07 09:48:00.864: ERROR/AndroidRuntime(9384): FATAL EXCEPTION: main
04-07 09:48:00.864: ERROR/AndroidRuntime(9384): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.bitgrind.wtb/com.bitgrind.wtb.activity.Main}: com.google.inject.b.q: com.google.inject.b.q: java.lang.annotation.IncompleteAnnotationException: The element optional is not complete for the annotation com.google.inject.Inject
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1622)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1638)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at android.app.ActivityThread.access$1500(ActivityThread.java:117)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:928)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at android.os.Handler.dispatchMessage(Handler.java:99)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at android.os.Looper.loop(Looper.java:123)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at android.app.ActivityThread.main(ActivityThread.java:3647)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at java.lang.reflect.Method.invokeNative(Native Method)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at java.lang.reflect.Method.invoke(Method.java:507)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at dalvik.system.NativeStart.main(Native Method)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384): Caused by: com.google.inject.b.q: com.google.inject.b.q: java.lang.annotation.IncompleteAnnotationException: The element optional is not complete for the annotation com.google.inject.Inject
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.b.do.a(MapMaker.java:553)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.b.do.a(MapMaker.java:419)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.b.w.get(CustomConcurrentHashMap.java:2041)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.b.av.b(FailableCache.java:46)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.q.a(ConstructorInjectorStore.java:52)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.n.a(ConstructorBindingImpl.java:57)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.aq.a(InjectorImpl.java:375)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.g.run(BindingProcessor.java:169)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.e.a(BindingProcessor.java:224)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.an.b(InjectorBuilder.java:120)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.an.a(InjectorBuilder.java:105)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.ab.a(Guice.java:92)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.ab.a(Guice.java:69)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.bitgrind.wtb.WTBApp.a(WTBApp.java:59)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at roboguice.application.RoboApplication.a_(RoboApplication.java:84)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at roboguice.activity.RoboActivity.a_(RoboActivity.java:192)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at roboguice.activity.RoboActivity.onCreate(RoboActivity.java:70)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.bitgrind.wtb.activity.Main.onCreate(Main.java:41)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1586)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     ... 11 more
04-07 09:48:00.864: ERROR/AndroidRuntime(9384): Caused by: com.google.inject.b.q: java.lang.annotation.IncompleteAnnotationException: The element optional is not complete for the annotation com.google.inject.Inject
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.b.do.a(MapMaker.java:553)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.b.do.a(MapMaker.java:419)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.b.w.get(CustomConcurrentHashMap.java:2041)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.b.av.b(FailableCache.java:46)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.br.a(MembersInjectorStore.java:66)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.q.b(ConstructorInjectorStore.java:69)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.q.a(ConstructorInjectorStore.java:31)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.r.a(ConstructorInjectorStore.java:35)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.b.aw.a(FailableCache.java:35)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.b.do.a(MapMaker.java:549)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     ... 30 more
04-07 09:48:00.864: ERROR/AndroidRuntime(9384): Caused by: java.lang.annotation.IncompleteAnnotationException: The element optional is not complete for the annotation com.google.inject.Inject
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at org.apache.harmony.lang.annotation.AnnotationFactory.invoke(AnnotationFactory.java:312)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at $Proxy1.optional(Native Method)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.e.n.<init>(InjectionPoint.java:85)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.e.p.a(InjectionPoint.java:384)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.e.n.a(InjectionPoint.java:353)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.e.n.b(InjectionPoint.java:295)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.br.b(MembersInjectorStore.java:78)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.br.a(MembersInjectorStore.java:35)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.bs.a(MembersInjectorStore.java:40)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.b.aw.a(FailableCache.java:35)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     at com.google.inject.b.do.a(MapMaker.java:549)
04-07 09:48:00.864: ERROR/AndroidRuntime(9384):     ... 39 more

这是我的(当前)proguard.cfg :(我尝试过很多东西)

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService

# Needed for RoboGuice, etc
-keepattributes SourceFile,LineNumberTable,RuntimeVisibleAnnotations,RuntimeVisibleParameterAnnotations,RuntimeVisibleFieldAnnotations
-keep public class com.google.inject.Inject
-keep,allowobfuscation public class com.google.inject.name.Named
-keep,allowobfuscation public class * implements com.google.inject.Provider
-keep,allowobfuscation @com.google.inject.Provides class *
-keep,allowobfuscation @com.google.inject.Provides class *
-keep,allowobfuscation @com.google.inject.ProvidedBy class * 
-keep,allowobfuscation @com.google.inject.Singleton class *
-keep,allowobfuscation @com.google.inject.BindingAnnotation class *
-keep,allowobfuscation @com.google.inject.ScopeAnnotation class *

-keep class com.google.inject.Binder

#-keep public class roboguice.**

-keepclassmembers class * {
    @com.google.inject.Inject <init>(...);
}

-keepclassmembers class com.google.inject.Inject {
    public boolean optional();
}

# Annotations
#-keepclasseswithmembernames class * {
#    public ** value();
#}

-keepclassmembers class * implements java.lang.annotation.Annotation { 
    ** *(); 
}

-keepclasseswithmembernames class * {
    native <methods>;
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
    public void set*(...);
}

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

# Guava primitives lexicographicalComparator() references sun.misc.Unsafe dynamically 
# which is obviously not provided in the Android Runtime
-dontwarn sun.misc.Unsafe

# Slf4j api is in libs for the server side stuff, not used in the app
-dontwarn org.slf4j.*

# Other dynamically referenced methods in Guava
-keepclassmembers class com.google.guava.* {
    void finalizeReferent();
    void startFinalizer(java.lang.Class,java.lang.Object);
}

# newBuilder() is referenced dynamically in generated ProtoBuf code
-keepclassmembers class * {
    ** newBuilder();
}

2 个答案:

答案 0 :(得分:8)

看起来不像是在保留注释。它们将被完全剥离,因为它们对代码的执行没有影响,而这真的很糟糕,因为检索的唯一方法是使用反射。

尝试添加

-keepattributes *Annotation*

答案 1 :(得分:3)

为了让RoboGuice 2为我工作,我必须将以下内容添加到我已经拥有的内容中:

-keep class com.google.inject.** { *; } 
-keep class javax.inject.** { *; } 
-keep class javax.annotation.** { *; } 
-keep class roboguice.** { *; } 

使用SDK中的非优化版本运行它。我的project.properties紧随其后。请注意,proguard-android.txt 不是 proguard-android-optimization.txt,后跟冒号字符和我的项目根目录中的自定义proguard.cfg。

/project.properties:

# ProGuard configuration
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard.cfg

我的决赛,这可能比我需要的更安全:

/proguard.cfg:

-keepattributes Signature
-keepattributes *Annotation*
-keep class roboguice.**

# if not using Google Maps library, safe to ignore these
-dontwarn roboguice.activity.RoboMapActivity
# safe to ignore testing classes, when proguard not being run against an instrumentation testing app
-dontwarn roboguice.test.**

-keep class com.google.inject.** { *; } 
-keepclassmembers class * {
    @com.google.inject.Inject <fields>;
    @com.google.inject.Inject <init>(...);
}
-keep class javax.inject.** { *; } 
-keep class javax.annotation.** { *; } 

# My application classes used by injection framework
-keep class com.myapp.RoboGuiceModule { *; }
-keep class com.myapp.AppProvider { *; }
-keep class com.myapp.MyInjectableSingletonExample { *; }
# ... other classes that are referenced in my custom RoboGuiceModule.configure() bindings