21
votes

I am using the following ProGuard rules:

-keepclassmembers class * extends org.greenrobot.greendao.AbstractDao { *; }
-keep class **$Properties

-keep class org.greenrobot.greendao.**
-keepclassmembers class org.greenrobot.greendao.** { *; }

# If you do not use SQLCipher:
-dontwarn org.greenrobot.greendao.database.**

# If you do not use RxJava:
-dontwarn rx.**

When starting the app I get the following crash log:

java.lang.RuntimeException: Unable to create application my.app.package.MyApplication: org.greenrobot.greendao.DaoException: Could not init DAOConfig
   at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4569)
   at android.app.ActivityThread.access$1500(ActivityThread.java:148)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:135)
   at android.app.ActivityThread.main(ActivityThread.java:5272)
   at java.lang.reflect.Method.invoke(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:372)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704)
Caused by: org.greenrobot.greendao.DaoException: Could not init DAOConfig
   at org.greenrobot.greendao.internal.DaoConfig.(Unknown Source)
   at org.greenrobot.greendao.AbstractDaoMaster.registerDaoClass(Unknown Source)
   at my.app.package.database.model.DaoMaster.(Unknown Source)
   at my.app.package.database.model.DaoMaster.(Unknown Source)
   at my.app.package.ZamgApplication.onCreate(Unknown Source)
   at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1011)
   at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4566)
   at android.app.ActivityThread.access$1500(ActivityThread.java:148) 
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
   at android.os.Handler.dispatchMessage(Handler.java:102) 
   at android.os.Looper.loop(Looper.java:135) 
   at android.app.ActivityThread.main(ActivityThread.java:5272) 
   at java.lang.reflect.Method.invoke(Native Method) 
   at java.lang.reflect.Method.invoke(Method.java:372) 
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909) 
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704) 
Caused by: java.lang.ArrayIndexOutOfBoundsException: length=5; index=6
   at org.greenrobot.greendao.internal.DaoConfig.reflectProperties(Unknown Source)
   at org.greenrobot.greendao.internal.DaoConfig.(Unknown Source) 
   at org.greenrobot.greendao.AbstractDaoMaster.registerDaoClass(Unknown Source) 
   at my.app.package.database.model.DaoMaster.(Unknown Source) 
   at my.app.package.database.model.DaoMaster.(Unknown Source) 
   at my.app.package.ZamgApplication.onCreate(Unknown Source) 
   at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1011) 
   at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4566) 
   at android.app.ActivityThread.access$1500(ActivityThread.java:148) 
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
   at android.os.Handler.dispatchMessage(Handler.java:102) 
   at android.os.Looper.loop(Looper.java:135) 
   at android.app.ActivityThread.main(ActivityThread.java:5272) 
   at java.lang.reflect.Method.invoke(Native Method) 
   at java.lang.reflect.Method.invoke(Method.java:372) 
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909) 
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704) 

When compiling the app without ProGuard, everything works fine.

Am I missing any configuration here? i couldn't find anything with Google on this...

5
fwiw: after 2 more days of digging, I decided to switch the database to realm.iomuetzenflo

5 Answers

13
votes

Do you keep the Entity class in your project?
If not, keep the package which you put your Entity class
like this
-keep class com.xxx.xxx.model.* {*;}

8
votes

I encountered the same problem

It seems that -keep class only guarantees that the class itself be retained, but its members may still be removed

In my case some static final fields of of a CustomDao$Properties class are removed, which eventually leads to an index out of bounds exception

replacing

-keep class **$Properties

with

-keep class **$Properties { *; }

solved my problem

2
votes

It seems that the instruction:

-keep class org.greenrobot.greendao.**

is not being applied. As you can see in the logs, lines like:

at org.greenrobot.a.c.a.a(Unknown Source)
at org.greenrobot.a.c.a.(Unknown Source) 
at org.greenrobot.a.b.a(Unknown Source) 

show that classes under org.greenrobot.greendao are being obfuscated while your ProGuard directive is telling (or was suppose to tell) ProGuard to leave them unchanged. To fix this, make sure that the ProGuard rules file where this is define is being correctly referenced in the proguardFiles section of your Android configuration:

proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

and that your release configuration(s) use the same proguard-rules.pro file.

1
votes

You can try this

-dontwarn org.greenrobot.greendao.**
-keepclassmembers class * extends de.greenrobot.dao.AbstractDao {

}
-keep class **$Properties

Use updated version

apply plugin: 'org.greenrobot.greendao'

compile 'org.greenrobot:greendao:3.2.0'

Same issues listed Here and here and on StackOverflow

1
votes
// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.
/** 
 * DAO for table "addresses".
*/
public class DbAddressDao extends AbstractDao<DbAddress, Long> {

    public static final String TABLENAME = "addresses";

    /**
     * Properties of entity DbAddress.<br/>
     * Can be used for QueryBuilder and for referencing column names.
    */
    public static class Properties {
        public final static Property Id = new Property(0, long.class, "id", true, "_id");
        public final static Property AddressLine = new Property(3, String.class, "addressLine", false, "ADDRESS_LINE");
    }

If you look into your Dao classes automatic generated by GreenDao library you can notice that it creates an inner class called Properties with each field you have into you database table like the example above.

You you pay attention on these fields you can notice that they are not being used in any part of the code because GreenDao uses reflection through DaoConfig class to get these fields. See the method reflectProperties into DaoConfig.

The problem is when you enable Proguard it understands that all these fields inside Properties is not being used anywhere so Proguard removes it.

So to avoid this to happen add the following lines into your Proguard file:

-keep class **$Properties
-keepclassmembers class **$Properties {
    public static <fields>;
}

This should solve the problem.