Only using Proguard: Could not init DaoConfig => ArrayIndexOutOfBoundsException
Asked Answered
F

6

21

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...

Fey answered 3/2, 2017 at 11:53 Comment(1)
fwiw: after 2 more days of digging, I decided to switch the database to realm.ioFey
H
14

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.* {*;}

Honan answered 15/2, 2017 at 2:55 Comment(2)
yes, i do. For testing purpose, I even kept my whole database package unobfuscated, but to no avail. Since I couldn't fix this after one week of trying and searching, I switched to realm.io. They have all proguard rules within the lib and there's nothng to do for the developer.Fey
perfectly solved my problem! This proguard rule should be added to the recommended proguard rules in the greendao official documentation.greenrobot.org/greendao/documentation/…Termitarium
L
9

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

Literate answered 25/6, 2019 at 8:56 Comment(2)
My app started crashing from nothing with this issue when using R8. This fixed it. Thanks! 🙏Orthogenic
As @Orthogenic said, this issue started occurring unexpectedly after R8 was released (even though I'm not aware of whether it's being used or not) and this is the only way to solve it. And I believe it's applicable to many more cases than just this specific GreenDao issue.Elswick
C
3

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.

Chuckhole answered 6/2, 2017 at 17:1 Comment(1)
thanks, I updated my rule set to keep almost everything from greendao. The log file is now a bit more verbose, but the error keeps happening. I updated my question with the new log and rules.Fey
I
1

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

Illogic answered 17/2, 2017 at 10:29 Comment(0)
O
1
// 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.

Onieonion answered 13/8, 2019 at 16:15 Comment(0)
F
0

Added lines below in proguard-rules.pro solved the issue for me.

-keepclassmembers class * extends org.greenrobot.greendao.AbstractDao {
public static java.lang.String TABLENAME;
}
-keep class **$Properties

thanks @mgpx

Flexed answered 28/10, 2021 at 15:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.