OrmLite and proguard obfuscation
OrmLite and proguard obfuscation

After some working on enterprise software for quite a long time I got used to using a ORM when dealing with structured storage so when writing application for Android it's hard to let go of that habit.

After searching for a while there was one ORM that was slightly better than the other I read about: OrmLite because it allowed me to easily write my own entities and had specific support for Android. The drawback is that it makes strong use of reflection (which might have some impact on performance).

I actually think that it should be possible to create a ORM that uses annotations and Annotation Processing Tool(apt) magic to easily create the entities. In fact I started to create such a thing but time is a wasting. Maybe in the future I'll get back to this project. I could probably use the same annotation names and interface as OrmLite... hummm.... :)

Some important things to look out when using OrmLite:

  • when using a DAO you have to do a explicit cast to Class or the java compiler will get utterly confused with the generics and refuse to compile. You can see an example code bellow. The examples provided with OrmLite actually don't compile unless you change them and force the casting. The error the compiler throws up is something like:
Error: type parameters of <D>D cannot be determined; no unique maximal instance exists for type variable D with upper bounds
    com.j256.ormlite.dao.Dao<java.lang.Object,java.lang.Integer>,
    com.j256.ormlite.dao.Dao<capture#296 of ?,?>

An example, assuming that there is a class Entity that is defined and annotated according to OrmLite rules:

    1: @SuppressWarnings ({ "rawtypes", "unchecked" })
    2: public class DBManager extends OrmLiteSqliteOpenHelper {
    3:         /* Fill with code... */
    4:         public Dao<Entity, Long> getEntityDAO () throws SQLException {
    5:                 return getDao ((Class)Entity.class);
    6:         }
    7: }

Note: this behaviour seams to go away with java 7 but Android SDK still requests version 6 and as the cast won't do you harm when compiling with jdk7 then I guess it's better, for the time being, to keep the cast in place.

  • if you want to use proguard to obfuscate your code then there are some rules you must add to your proguard configuration:
# for ormlite stuff
-keep class com.j256.**
-keepclassmembers class com.j256.** {*;}
-keep enum com.j256.**
-keepclassmembers enum com.j256.**  {*;}
-keep interface com.j256.**
-keepclassmembers interface com.j256.**  {*;}

# keep the classes and members of our entities or OrmLite will not work
-keep class our.package.with.database.entities.**
-keepclassmembers our.package.with.database.entities.** {*;}

This should be, hopefully, enough to keep proguard from obfuscation the classes that OrmLite needs to use via reflection.