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 :)
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
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.
Most helpful comment
Your model classes are renamed and you should keep them for your particular use-case using
And for
dataClass.getDeclaredMethod("get"+primaryKeyFieldName, null);you probably need