This bug is reproducible with v5.3.3. I'm using ProGuard only to shrink, not to obfuscate or optimize. I noticed this bug when trying to use AspectJ, but it works with some other annotations too. Here's an exmaple AspectJ class representing an aspect using some annotations:
@Aspect public class MyAspect { @Pointcut("execution(* com.amazonaws.services.dynamodb*.*AmazonDynamoDB.*(..))") public void myPointCut() { } @Around(value = "myPointCut()") public Object logExecution(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println(joinPoint); return joinPoint.proceed(); } }
Then I use config which explicitly tells ProGuard in as many explicit ways as I possibly can not to mess with this com.myproject.MyAspect
class, not to mess with any class using the @Aspect annotation, and to keep all annotations in general:
-forceprocessing -dontobfuscate -dontoptimize -dontwarn -dontnote -dontskipnonpubliclibraryclasses -dontskipnonpubliclibraryclassmembers -libraryjars <java.home>/lib -keep @org.aspectj.lang.annotation.Aspect class ** -keep class com.myproject.MyAspect {*;} -keep @interface *
The result is that it keeps everything, including the annotations... except for the "myPointCut()" parameter which was being passed to the @Around annotation. Weirdly enough though, it does keep the parameter in the @Pointcut annotation. See below:
@Aspect public class MyAspect { @Pointcut("execution(* com.amazonaws.services.dynamodb*.*AmazonDynamoDB.*(..))") public void myPointCut() { } @Around public Object logExecution(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println(joinPoint); return joinPoint.proceed(); } }
Not surprisingly, this change breaks AspectJ. I should also note that I've tried many other variations of this config to try to fix this issue, including -keepattributes *Annotation*
which is only supposed to be used for obfuscation, but none of them fixed the issue.
I was also able to reproduce this issue on v6.0.2
This bug also occurs with the
javax.inject.Named
annotation, but not with theorg.springframework.beans.factory.annotation.Value
annotation.Thanks for the clear report. Java bytecode represents the parameters in annotation classes as methods. ProGuard probably doesn't see that AspectJ is using the method, and removes it. You can keep the annotation parameters with
I don't see right away why the method appears unused in this case -- preseumably more reflection in AspectJ.
Thanks so much! Changing the config value
-keep @interface *
to-keep @interface * {*;}
seems to have fixed it! It would be great if the documention had a section which talked more about annotations and how to configure ProGuard to deal with them as you want it to. I should note that I still think this is a bug since I'm obviously using the given annotation parameters in my code, so ProGuard should know better than to remove them since I'm telling it to keep the class and the annotation.