24

I have an app that uses ActiveAndroid, a database ORM library, that relies on annotations.

@Table(name="test")
public class DatabaseItem extends ActiveRecordBase<DatabaseItem> {

    public DatabaseItem(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    @Column(name="counter")
    public int counter;

}

How do I get Proguard working nicely with this? Currently, I get errors about not finding a column name by ActiveAndroid when using Proguard. I guess it somehow mangles the annotation.

My relevant Proguard configuration:

#ActiveAndroid
-keep public class com.activeandroid.**
-keep public class * extends com.activeandroid.ActiveRecordBase
-keepattributes Column
-keepattributes Table
Nathan
  • 8,093
  • 8
  • 50
  • 76
Peterdk
  • 15,625
  • 20
  • 101
  • 140

5 Answers5

37

Column and Table aren't existing java class file attributes. You'll at least have to specify

-keepattributes *Annotation*

Cfr. the ProGuard manual.

Eric Lafortune
  • 45,150
  • 8
  • 114
  • 106
  • Assuming that `Table` and `Column` are both attributes applied to a class, I would say at a minimum `-keepattributes RuntimeVisibleAnnotations` needs to be applied. `*Annotation*` is overly inclusive, including annotations on parameters, type parameters, and runtime invisible annotations. – Steven Jeuris Oct 11 '21 at 08:33
16

In March 2013, Proguard version 4.9 was released, one of the fixes were:

Fixed overly aggressive shrinking of class annotations. 

So make sure that your Proguard version is up to date and then use Eric Lafortune's solution:

-keepattributes *Annotation*

You can also use this configuration to store all class members that has a specific annotation:

-keepclassmembers class * {
    @fully.qualified.package.AnnotationType *;
}
Simon Forsberg
  • 13,086
  • 10
  • 64
  • 108
5

Solution was to keep all members of the library and the database classes

-keep class com.activeandroid.**
{
     *;
}
-keep public class my.app.database.**
{
    *;
}
-keepattributes Column
-keepattributes Table
Peterdk
  • 15,625
  • 20
  • 101
  • 140
  • 2
    I used this, but instead of the two lines of "-keepattributes" I used this only line: "-keepattributes \*Annotation\*", as indicated by Eric Lafortune and Simon André Forsberg. Everything worked fine now! – PFROLIM Mar 07 '14 at 00:12
  • "Column" and "Table" are invalid options for `-keepattributes`. You [can't pass annotation names to keep](https://stackoverflow.com/a/69523469/590790). – Steven Jeuris Oct 11 '21 at 08:53
2

For those only using Gradle, the solution is very similar (note the single quotes around the Annotation):

keep 'public class java.package.** { *; }'

keepattributes '*Annotation*'

This is especially useful if you are using JSON serialization annotations (e.g., Jackson or the like) in a vanilla Gradle project.

John S.
  • 71
  • 1
  • 6
0

This what worked in my case:

-keep class com.activeandroid.** { *; }
-keep class com.activeandroid.**.** { *; }
-keep class * extends com.activeandroid.Model
-keep class * extends com.activeandroid.serializer.TypeSerializer
-keep public class * extends com.activeandroid.ActiveRecordBase

-keepattributes Column
-keepattributes Table
-keepattributes *Annotation*
-keepclasseswithmembers class * { @com.activeandroid.annotation.Column <fields>; }
Hamzeh Soboh
  • 7,572
  • 5
  • 43
  • 54
  • 1
    "Column" and "Table" are invalid options for `-keepattributes`. You [can't pass annotation names to keep](https://stackoverflow.com/a/69523469/590790). – Steven Jeuris Oct 11 '21 at 08:55