Proguard configuration to keep members with an annotation that has parameters

We are obfuscating our project with Proguard and are using picocli for some command line tools. We have Java code something like the following

@picocli.CommandLine.Option(names = { "--argument", "-a" }, description = "An argument", required = true)  
private String testArgument;

and we want to exclude ‘testArgument’ from the obfuscation as this field name can be shown to the user by picocli. The classes defining the different picocli options and commands do not share an interface or common extension point and I don’t really want to add one if I can help it. With the following configuration I can keep the field if I change the annotation in the code to Java’s @Deprecated

-keepclassmembers class * {
    @java.lang.Deprecated <fields>;
}

which makes me think we can’t be too far away but it seems that the parameters in the annotation are causing the problem and we can’t quite figure out the syntax to incorporate them into the proguard configuration. We have tried things like

@picocli.CommandLine.Option* <fields>;
@picocli.CommandLine.Option... <fields>;
@picocli.CommandLine.Option?*? <fields>;

none of which have produced the result we need.

Is there configuration we’re missing which will keep these field names or does Proguard not support annotations with parameters?

Thanks for any suggestions

Hi @iwayguys,

Welcome to the Guardsquare Community!

Can you try the following?

-keepclassmembers class * {
    @picocli.CommandLine$Option <fields>;
}

This configuration tells ProGuard to keep all field members in any class (class * ) that are annotated with @picocli.CommandLine.Option . I would expect this will do the trick for you.

Once you make this change, please clean your build cache and rebuild (gradle clean assembleRelease ) and see if the issue is resolved.

If this rule alone does not achieve the desired effect, you might consider combining it with a broader rule and then narrowing it down from there. Here’s a more inclusive approach, which you can gradually restrict as you confirm what works:

-keepclasseswithmembers class * {
    @picocli.CommandLine$Option *;
}

Please let me know if anything is not clear.
Kind Regards,
Jack

2 Likes