title: Problem with ProGuard and RoboGuice with @Inject annotations
body: <p>I'm having some problems with proguard when optimizing my android app. It seems that there is something done to an annotation class (@com.google.inject.Inject) which Dalvik/Harmony is not happy with at runtime.</p>
  
  <blockquote>
    <p><strong>java.lang.annotation.IncompleteAnnotationException:</strong>
    The element optional is not complete
    for the annotation
    com.google.inject.Inject</p>
  </blockquote>
  
  <p>com.google.inject.Inject looks like this (Part of Guice):</p>
  
  <pre><code>@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;
  }
  </code></pre>
  
  <p>Here's the failure on launch:</p>
  
  <pre><code>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.&lt;init&gt;(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
  </code></pre>
  
  <p>And this is my (current) proguard.cfg: (I've tried many things)</p>
  
  <pre><code>-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 &lt;init&gt;(...);
  }
  
  -keepclassmembers class com.google.inject.Inject {
      public boolean optional();
  }
  
  # Annotations
  #-keepclasseswithmembernames class * {
  #    public ** value();
  #}
  
  -keepclassmembers class * implements java.lang.annotation.Annotation { 
      ** *(); 
  }
  
  -keepclasseswithmembernames class * {
      native &lt;methods&gt;;
      public &lt;init&gt;(android.content.Context, android.util.AttributeSet);
      public &lt;init&gt;(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();
  }
  </code></pre>