How should I use proguard with ormlite library on Android?
Trying this:
-keep class com.j256.**
-keepclassmembers class com.j256.**
-keep enum com.j256.**
-keepclassmembers enum com.j256.**
-keep interface com.j256.**
-keepclassmembers interface com.j256.**
But I get:
03-23 20:23:54.518: E/AndroidRuntime(3032): java.lang.RuntimeException: Unable to start activity ComponentInfo{cz.eman.android.cepro/cz.eman.android.cepro.activity.StationsOverviewActivity}: java.lang.IllegalStateException: Could not find constructor that takes a Context argument for helper class class kb
I also tried to add this:
-keepclassmembers class * { public <init>(android.content.Context); }
But I get another classmembers errors.
Thank you a lot for posts like this that help us to advance step by step.
I've came up with other solution after i have tried the last one without success:
# OrmLite uses reflection
-keep class com.j256.**
-keepclassmembers class com.j256.** { *; }
-keep enum com.j256.**
-keepclassmembers enum com.j256.** { *; }
-keep interface com.j256.**
-keepclassmembers interface com.j256.** { *; }
I hope it can help someone.
The accepted answer was not enough for my case, so I enhanced it and this is what I ended up with:
# OrmLite uses reflection
-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 helper class and its constructor
-keep class * extends com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper
-keepclassmembers class * extends com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper {
public <init>(android.content.Context);
}
# Keep the annotations
-keepattributes *Annotation*
# Keep all model classes that are used by OrmLite
# Also keep their field names and the constructor
-keep #com.j256.ormlite.table.DatabaseTable class * {
#com.j256.ormlite.field.DatabaseField <fields>;
#com.j256.ormlite.field.ForeignCollectionField <fields>;
# Add the ormlite field annotations that your model uses here
<init>();
}
I don't have the solution but here are a couple of references to help:
Proguard support request around ORMLite
ORMLite proguard discussion #1
ORMLite proguard discussion #2
You may be missing:
-keepclassmembers class * {
public <init>(android.content.Context);
}
and/or
-keepattributes *Annotation*
A small addition to the configuration above - if you're trying to serialize / deserialize Joda's DateTime objects via ORMLite, you probably need this as well:
-keepclassmembers class **DateTime {
<init>(long);
long getMillis();
}
...since ORMLite's DateTimeType does everything via reflection.
In addittion to default necessary for reflection:
# OrmLite uses reflection
-keep class com.j256.**
-keepclassmembers class com.j256.** { *; }
-keep enum com.j256.**
-keepclassmembers enum com.j256.** { *; }
-keep interface com.j256.**
-keepclassmembers interface com.j256.** { *; }
I needed to keep all my Entity classes:
-keep class com.example.db.Entities.** { *; }
Otherwise entity classes are stripped out.
I use predefined DB(generated earlier).
Is there an easier/better way to obfuscate. Maybe I'm keeping too many classes?
In my case this did the trick:
-keepattributes SourceFile,LineNumberTable,Signature,InnerClasses,*Annotation*
and
-keepclassmembers class * {public <init>(android.content.Context);}
-keep class com.j256.** { *; }
With obfucation and optimizations.
A small addition for the latest version OrmLite 5.
You may want to add these rows to hide some new warnings:
-dontwarn com.j256.ormlite.android.**
-dontwarn com.j256.ormlite.logger.**
-dontwarn com.j256.ormlite.misc.**
Warnings are like these:
Warning:com.j256.ormlite.android.OrmliteTransactionalProcessor: can't
find referenced class javax.lang.model.SourceVersion
Warning:com.j256.ormlite.logger.Slf4jLoggingLog: can't find referenced
class org.slf4j.LoggerFactory
Warning:com.j256.ormlite.misc.JavaxPersistenceImpl: can't find
referenced class javax.persistence.Column
I've came up with such solution (maybe will work for somebody too).
Made such changes to proguard.cfg:
Added -dontobfuscate option
Appended ,!code/allocation/variable to -optimization option
APK file size using such configuration reduced from 580 kB to 250 kB.
Though, no obfuscation is performed.
Related
I'm building an Android app using Android Gradle Plugin 4.1.0 and Gradle 6.5.1. In my build.gradle file the flag minifyEnabled has the value true. This is my proguard-rules.pro file:
#rx
-dontwarn rx.**
-keep class rx.** { *; }
#retrofit / okhttp
-dontwarn retrofit.**
-keep class retrofit.** { *; }
-keep class okio.** { *; }
-keep class com.squareup.okhttp.** { *; }
-keep interface com.squareup.okhttp.** { *; }
-dontwarn com.squareup.okhttp.**
-dontwarn okhttp3.internal.platform.**
-dontwarn okio.**
-dontwarn org.conscrypt.**
#gson
-keepattributes SerializedName
-keep class com.google.gson.** { *; }
-keep class sun.misc.Unsafe { *; }
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
-keepclassmembers enum * { *; }
-keepattributes Signature
-keepattributes Exceptions
-keepattributes *Annotation*
-dontwarn javax.annotation.Nullable
-dontwarn javax.annotation.ParametersAreNonnullByDefault
-dontwarn javax.annotation.concurrent.GuardedBy
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
#guava
-dontwarn afu.org.checkerframework.checker.formatter.**
-dontwarn afu.org.checkerframework.checker.nullness.**
-dontwarn afu.org.checkerframework.checker.regex.**
-dontwarn afu.org.checkerframework.checker.units.**
-keep class * implements ru.surfstudio.android.network.Transformable
-keep class * implements ru.surfstudio.android.network.response.BaseResponse
-dontwarn com.bumptech.glide.**
#firebase crashlytics
-printmapping mapping.txt
-keepattributes *Annotation*,SourceFile,LineNumberTable
-keep public class * extends java.lang.Exception
-keep class com.google.firebase.crashlytics.** { *; }
-dontwarn com.google.firebase.crashlytics.**
#kotlin-reflect
#https://stackoverflow.com/questions/45871970/kotlin-reflect-proguard-smallsortedmap
-dontwarn kotlin.reflect.jvm.internal.**
#Cashoff javascript interface
-keep class ru.sbi.android.f_analytics.analytics.CashoffInteface { *; }
-dontwarn ru.sbi.android.f_main.R$id
-keep class ru.sbi.android.ui.navigation.MainTabType
#Cross-feature navigation keeps
-keep interface ru.sbi.android.ui.fragment.CrossFeatureFragment {*;}
-keep class * implements ru.sbi.android.ui.fragment.CrossFeatureFragment
#android standard
-keep class ru.surfstudio.android.rx.extension.ConsumerSafe { *; }
-keep class ru.surfstudio.android.rx.extension.ActionSafe { *; }
#AndroidPdfViewer
-keep class com.shockwave.pdfium.util.Size
#firebase
-dontwarn com.google.firebase.messaging.**
#android material
-keep class com.google.android.material.** { *; }
-dontwarn com.google.android.material.**
#Если вы хотите применять новый API Google API для отслеживания инициаторов
-dontwarn com.android.installreferrer.com.android.installreferrer
-ignorewarnings
I see lots of minifyReleaseWithR8 tasks being executed during the build.
But when I'm decompiling the resulting APK using apktool I see that all the package, class, methods names are the same as in my Android Studio. How can I understand why R8 doesn't obfuscate the code?
You have a keep rule for every single class you use in your app. If you have a -keep rule matching a class it will be kept and not obfuscated. For obfuscation to rename items (classes/fields and methods) that either have to not be matched by a keep rule (or matched by a keep rule with modifier allowobfuscation).
Keep rules are only required for items which are looked up through reflection, so you will have to trim down your rules to a much smaller set. I suggest that you start out by an empty proguard-rules.pro and only get what getDefaultProguardFile('proguard-android-optimize.txt') generates (like here). Then your app might not work, but then you can figure out what is going wrong and start adding additional rules. One way to start there is to only keep the classes in you own application package (-keep class ru.sbi.android.** { *; }), as libraries normally does not need keep rules, and then try to trim that further.
Please take a look at Shrink, obfuscate, and optimize your app as well.
I am having problems with GSON on Android with Proguard.
APK is compiled, installed on phone.
Application is not crashing, it is just not parsing object correctly.
I log all the data and it is like that:
I get correct string with data to parse.
(CookieValue is correct)
Token token = new Gson().fromJson(cookieValue, Token.class);
After this line, I am logging this object and it is having only null values inside.
My Proguard GSON:
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# For using GSON #Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-dontwarn sun.misc.**
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
-keep class com.google.gson.examples.android.model.** { *; }
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
-keep public class com.google.gson
Token rules:
-dontwarn com.project.package.model.oauth.**
-keep,allowshrinking class com.project.package.oauth.Token { *; }
Yes, I have tried this configuration https://github.com/google/gson/blob/master/examples/android-proguard-example/proguard.cfg
Any suggestions?
In this line:
- keep,allowshrinking class com.project.package.oauth.Token { *; }
Do you actually have a space between the dash and keep? If so, take that out and see if it helps.
You might also want to remove the space after the dash in the previous dontwarn line, as well.
You can find it in my collection :
https://github.com/thientvse/awesome-mobile-collections/blob/master/README.md
It will help you config almost lib in proguard file.
I hope it will help your problem!
I have a few models that I want to obfuscate in my code.
I know that I could just ignore the whole model package but I don't want to do that.
I tried a few proguard tweaks and checked all relevant posts to no avail. ORMlite keeps throwing java.lang.RuntimeException: Unable to create application ...App: java.lang.IllegalArgumentException: Foreign field class ....f.p does not have id field. I checked that the annotation is still there with dex2jar and jd, and it is still there.
I have this proguard configuration (and a lot more that obfuscates other parts):
aggressive stuff :
-mergeinterfacesaggressively
-allowaccessmodification
-optimizationpasses 5
-verbose
-dontskipnonpubliclibraryclasses
-dontpreverify
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
keep information needed by various frameworks:
-keepattributes *Annotation*
-keepattributes Signature
-keepattributes EnclosingMethod
ORMLITE related:
-keep class com.j256.**
-keepclassmembers class com.j256.** { *; }
-keep enum com.j256.**
-keepclassmembers enum com.j256.** { *; }
-keep interface com.j256.**
-keepclassmembers interface com.j256.** { *; }
Am I missing something or is this just not possible?
As ORMLite uses reflection to save or retain your data, they want un-obfuscated name of entity (ie classes you are using to save or retain data).
This exception is thrown because ORMLite is trying to find the Entity classes for its tables and its not able to find the classes and members with similar name.
Just Ignore your entity classes from getting obfuscated using following code:
-keep class com.xyz.components.**
-keepclassmembers class com.xyz.components.** { *; }
where com.xyz.components is your package for Entity classes.
I hope this helps!
In addition to Vivek Soneja's answer:
There is a way to keep entity classes independently from their packages:
-keep #com.j256.ormlite.table.DatabaseTable class * {
#com.j256.ormlite.field.DatabaseField <fields>;
#com.j256.ormlite.field.ForeignCollectionField <fields>;
<init>();
}
It will keep all DatabaseTable annotated classes as well as their DatabaseField and ForeignCollectionField annotated fields
How should I use proguard with ormlite library on Android?
Trying this:
-keep class com.j256.**
-keepclassmembers class com.j256.**
-keep enum com.j256.**
-keepclassmembers enum com.j256.**
-keep interface com.j256.**
-keepclassmembers interface com.j256.**
But I get:
03-23 20:23:54.518: E/AndroidRuntime(3032): java.lang.RuntimeException: Unable to start activity ComponentInfo{cz.eman.android.cepro/cz.eman.android.cepro.activity.StationsOverviewActivity}: java.lang.IllegalStateException: Could not find constructor that takes a Context argument for helper class class kb
I also tried to add this:
-keepclassmembers class * { public <init>(android.content.Context); }
But I get another classmembers errors.
Thank you a lot for posts like this that help us to advance step by step.
I've came up with other solution after i have tried the last one without success:
# OrmLite uses reflection
-keep class com.j256.**
-keepclassmembers class com.j256.** { *; }
-keep enum com.j256.**
-keepclassmembers enum com.j256.** { *; }
-keep interface com.j256.**
-keepclassmembers interface com.j256.** { *; }
I hope it can help someone.
The accepted answer was not enough for my case, so I enhanced it and this is what I ended up with:
# OrmLite uses reflection
-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 helper class and its constructor
-keep class * extends com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper
-keepclassmembers class * extends com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper {
public <init>(android.content.Context);
}
# Keep the annotations
-keepattributes *Annotation*
# Keep all model classes that are used by OrmLite
# Also keep their field names and the constructor
-keep #com.j256.ormlite.table.DatabaseTable class * {
#com.j256.ormlite.field.DatabaseField <fields>;
#com.j256.ormlite.field.ForeignCollectionField <fields>;
# Add the ormlite field annotations that your model uses here
<init>();
}
I don't have the solution but here are a couple of references to help:
Proguard support request around ORMLite
ORMLite proguard discussion #1
ORMLite proguard discussion #2
You may be missing:
-keepclassmembers class * {
public <init>(android.content.Context);
}
and/or
-keepattributes *Annotation*
A small addition to the configuration above - if you're trying to serialize / deserialize Joda's DateTime objects via ORMLite, you probably need this as well:
-keepclassmembers class **DateTime {
<init>(long);
long getMillis();
}
...since ORMLite's DateTimeType does everything via reflection.
In addittion to default necessary for reflection:
# OrmLite uses reflection
-keep class com.j256.**
-keepclassmembers class com.j256.** { *; }
-keep enum com.j256.**
-keepclassmembers enum com.j256.** { *; }
-keep interface com.j256.**
-keepclassmembers interface com.j256.** { *; }
I needed to keep all my Entity classes:
-keep class com.example.db.Entities.** { *; }
Otherwise entity classes are stripped out.
I use predefined DB(generated earlier).
Is there an easier/better way to obfuscate. Maybe I'm keeping too many classes?
In my case this did the trick:
-keepattributes SourceFile,LineNumberTable,Signature,InnerClasses,*Annotation*
and
-keepclassmembers class * {public <init>(android.content.Context);}
-keep class com.j256.** { *; }
With obfucation and optimizations.
A small addition for the latest version OrmLite 5.
You may want to add these rows to hide some new warnings:
-dontwarn com.j256.ormlite.android.**
-dontwarn com.j256.ormlite.logger.**
-dontwarn com.j256.ormlite.misc.**
Warnings are like these:
Warning:com.j256.ormlite.android.OrmliteTransactionalProcessor: can't
find referenced class javax.lang.model.SourceVersion
Warning:com.j256.ormlite.logger.Slf4jLoggingLog: can't find referenced
class org.slf4j.LoggerFactory
Warning:com.j256.ormlite.misc.JavaxPersistenceImpl: can't find
referenced class javax.persistence.Column
I've came up with such solution (maybe will work for somebody too).
Made such changes to proguard.cfg:
Added -dontobfuscate option
Appended ,!code/allocation/variable to -optimization option
APK file size using such configuration reduced from 580 kB to 250 kB.
Though, no obfuscation is performed.
When I use Proguard on project with OrmLite. I recieve this error:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.package.name/com.package.name.activities.StartActivity}:
java.lang.IllegalStateException: Could not find OpenHelperClass because none of the generic parameters of class class com.package.name.activities.StartActivity extends OrmLiteSqliteOpenHelper. You should use getHelper(Context, Class) instead.
I've tried all recomendation from Proguard with OrmLite on Android and from others resources but without results
Put the below in both your proguard-project file and your proguard-optimization file (if you use optimization).
# Your application may contain more items that need to be preserved;
# typically classes that are dynamically created using Class.forName:
# ormlite uses reflection
-keep class com.j256.** { *; }
-keep class com.j256.**
-keepclassmembers class com.j256.**
-keep enum com.j256.**
-keepclassmembers enum com.j256.**
-keep interface com.j256.**
-keepclassmembers interface com.j256.**
-keepclassmembers class * {
public <init>(android.content.Context);
}
-keepattributes *Annotation*
and for every model class:
-keep class com.xyz.components.**
-keepclassmembers class com.xyz.components.** { *; }
I don't like the last part one bit, but I'm tired of trying to find a better solution.
I asked much the same question crash using ORMLite on Android with proguard and the answer was to add
-keepattributes Signature
to the proguard configuration.
You can use the following proguard configuration to Keep all model classes that are used by OrmLite
-keep #com.j256.ormlite.table.DatabaseTable class * {
#com.j256.ormlite.field.DatabaseField <fields>;
#com.j256.ormlite.field.ForeignCollectionField <fields>;
# Add the ormlite field annotations that your model uses here
<init>();
}
Just a small addition for the latest version OrmLite 5.
You may want to add these rows to hide some new warnings:
-dontwarn com.j256.ormlite.android.**
-dontwarn com.j256.ormlite.logger.**
-dontwarn com.j256.ormlite.misc.**
Look for more details into this thread: "how can i write the config of proguard for ormlite?"