Realm-java: Reflection issue with proguard

Created on 4 Jul 2017  路  2Comments  路  Source: realm/realm-java

Hello guys,

I want to achieve obfuscation of my code with Proguard and running into some problems with my release version. I've written a custom method which uses reflection to get the primaryKey field and method of a given RealmObject. The method is shown below.

    private static void fetchUUID(RealmObject dataObject)  {
      if (dataObject != null) {

        Class dataClass = loadDataClass(dataObject);

        Log.d("debug", "get schema:" + Realm.getDefaultInstance().getSchema().get(dataClass.getSimpleName()));
        String primaryKeyFieldName = Realm.getDefaultInstance().getSchema().get(dataClass.getSimpleName()).getPrimaryKey();
        Method primaryKeyGetter = dataClass.getDeclaredMethod("get"+primaryKeyFieldName, null);
        String uuid = String.valueOf(primaryKeyGetter.invoke(dataObject));

        //do something with the uuid ...
    }
}

private static Class loadDataClass(RealmObject object) {

    if(object.getClass().getSimpleName().endsWith("RealmProxy")) {
        return object.getClass().getSuperclass();
    }

    return object.getClass();
}

In the debug version everything works fine. But in the release version the line
Log.d("debug", "get schema:" + Realm.getDefaultInstance().getSchema().get(dataClass.getSimpleName()));
prints "get schema null" and according to this the following code crashes immediately. Unfortunately the crash log isn't really helpful because it's still obfuscated and I got no idea how to deobfuscate the realm library code ^^

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String io.realm.cz.e()' on a null object reference

My build.gradle contains the following content

release {
            minifyEnabled true
            shrinkResources false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }

and my proguard-rules.pro

-dontoptimize

# Prevent Okio Errors
-dontwarn okio.**
-dontwarn javax.annotation.Nullable
-dontwarn javax.annotation.ParametersAreNonnullByDefault

# Prevent Retrofit2 Errors
-dontwarn retrofit2.**

-keepattributes InnerClasses

-keep class **.R
-keep class **.R$* {
    <fields>;
}

-keep class io.realm.annotations.RealmModule
-keep @io.realm.annotations.RealmModule class *
-keep class io.realm.internal.Keep
-keep @io.realm.internal.Keep class *
-dontwarn javax.**
-dontwarn io.realm.**

Do you know whats wrong here? Do I need a special configuration for using realm with ProGuard and reflection?

Thanks in advance :)

Version of Realm and tooling

Realm version(s): 3.3.2
Realm sync feature enabled: no
Android Studio version: 2.3.3
Which Android version and device: 7.0 / Sony XPeria Z5

T-Help

Most helpful comment

Your model classes are renamed and you should keep them for your particular use-case using

-keepnames public class * extends io.realm.RealmObject

And for dataClass.getDeclaredMethod("get"+primaryKeyFieldName, null); you probably need

-keep public class * extends io.realm.RealmObject { *; }

All 2 comments

Your model classes are renamed and you should keep them for your particular use-case using

-keepnames public class * extends io.realm.RealmObject

And for dataClass.getDeclaredMethod("get"+primaryKeyFieldName, null); you probably need

-keep public class * extends io.realm.RealmObject { *; }

Thank you so much, that does the trick. :) So it was just my fault and no bug in the realm library.

Was this page helpful?
0 / 5 - 0 ratings