I need to keep all model classes to be unobfuscated, so I added this line in proguard rules to keep all model classes:
-keep class my_package_name.model.** { *; }
All model classes are getting kept by this command but still, it is obfuscating the annotations inside the Model classes. I tried adding the following line:
-keepattributes *Annotation*
-keepattributes EnclosingMethod
But still, results are same. My model classes contain these two annotations:
#SerializedName("message")
#Expose
private String message;
How can I keep the two annotations unobfuscated?
Try this:
-keepattributes *Annotation*
-keepattributes Signature
-dontnote sun.misc.**
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
Actually, there is a proguard config in official repo on github https://github.com/google/gson/blob/master/examples/android-proguard-example/proguard.cfg
Gson uses generic type information stored in a class file when working with fields.
Proguard removes such information by default, so configure it to keep all of it.
Trying adding
-keepattributes Signature
-keepattributes EnclosingMethod
-keepattributes InnerClasses
-keepattributes Annotation
For using GSON #Expose annotation
-keepattributes *Annotation*
For Gson specific classes
-keep class sun.misc.Unsafe { *; }
Prevent proguard from stripping interface information from TypeAdapterFactory,JsonSerializer, JsonDeserializer instances (so they can be used in #JsonAdapter)
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
-keep #package.annotationclassname public class *
The rule
-keep class com.google.gson.annotations.*
will keep all annotations in the package com.google.gson.annotations including the SerializedName and Expose ones that you have used.
Add to your proguard : It's preventing specific classes to be obfuscated.
Mandatory : -dontshrink. : https://www.guardsquare.com/en/proguard/manual/usage
Not mandatory : try to use -dontoptimize.
I don't really understand the issue, are you referring to a field or inner class ?
If you have an inner class inside a class, you need to specify its inner fields.
For example, if this is the class :
public class Parent {
protected Child child;
protected class Child {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
}
In the proguard, you need to specify Child class :
-keep class com.package.name.Parent$Child {*; }
You may Need To Create an annotation called DontObfuscate in your project
for more check this
Managing obfuscation with annotations
Related
The project working well without enabling proguard, the problem comes when enable it, I am using retrofit with Moshi converter and Coroutines to fetch list of data, and Hilt for DI, and I added all rules and kept all models
This is the error:
Could not compute caller for function: public constructor MovieListEntity(movie_data: kotlin.collections.List<com...domain.entities.MovieData>) defined in com...domain.entities.MovieListEntity[c#dad1eb0] (member = null)
And these are the classes mentioned
data class MovieListEntity(
#field:Json(name = "movie_data")
val movie_data: List<MovieData>
)
data class MovieData(
#field:Json(name = "movie_id")
val movie_id: Int,
#field:Json(name = "sub_title")
val sub_title: String,
#field:Json(name = "title")
val title: String
)
Note: I tried also without annotations, and it didn't help
These are the proguard rules:
-keep class com.***.***.domain.entitie.** { *; }
-keep class com.***.***.domain.entities.*
-keep class com.***.***.domain.entities.MovieListEntity
-keep class com.***.***.domain.entities.MovieData
-keep class com.***.***.DataBinderMapperImpl { *; }
-keep class com.***.***.DataBinderMapperImpl { *; }
-keep class com.***.*****{
public ** component1();
<fields>;
}
Plus other rules for retrofit, OkHttp, hilt .. etc.
How Can I solve this error?
Solved by adding these rules
-keepclassmembers class kotlin.Metadata {
public <methods>;
}
-keepclassmembers class * {
#com.squareup.moshi.FromJson <methods>;
#com.squareup.moshi.ToJson <methods>;
}
-keepnames #kotlin.Metadata class com.******.domain.entities.**
-keep class com.******.domain.entities.** { *; }
-keepclassmembers class com.*****.domain.entities.** { *; }
The problem was in Moshi library, check this
Current situation
I have a model, where class UserSettingModel have two field : long UserId and have as field one exemplar of class UserSettings ( with many field ) with name Settings.
WARNING : none of this fields used directly in my code ( in Android Studio color of this fields is gray), but I need to resend it to server.
public class UserSettingsModel
{
#SerializedName("UserId")
public long UserId = -1L;
#SerializedName("Settings")
public UserSettings Settings;
}//end of class/ UserSettingsModel
class UserSettings
{
#SerializedName("showRegion")
public String showRegion = "";
#SerializedName("showAddress")
public String showAddress = "";
}
Problem
If working with apk in DEBUG mode : GSON deserialize all field of class UserSettingModel, including Settings
If working with apk in RELEASE mode : field Settings - not deserialize
My proguard :
-keepattributes Signature
-keepattributes *Annotation*
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
-keep class com.google.gson.examples.android.model.** { *; }
-keep class com.google.gson.** { *; }
-keepclassmembers enum * { *; }
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
What I need
How to serialize/deserialize with GSON in Release mode ALL FIELD of classes, also with warning "field is never used" ?
This is because of obfuscation, as DQuade states in the comment.
To prevent gradle from removing them, you can either add the specific class in your proguard-rules.pro file:
-keepclassmembers class [yourPackageName].UserSettingsModel
-keepclassmembers class [yourPackageName].UserSettings
or prevent gradle from removing all members annotated with the SerializedName annotation:
-keepclassmembers class * {
#com.google.gson.annotations.SerializedName <fields>;
}
I want to keep the class name and class fields names of all classes that have my custom Annotation:
#Retention(CLASS)
#Target(ElementType.TYPE)
public #interface DoNotObfuscate {
}
I tried this:
-keep #com.mypackage.DoNotObfuscate public class *
but that did not work.
In order to keep class fields you should add "{*;}" at the end:
-keep #com.mypackage.DoNotObfuscate public class * {*;}
I'm using the android "Groundy" library containing the GroundTask class, which makes use of annotations. Further I created a class
public class DownloadTask extends GroundyTask
and a callback object:
private final Object mCallback = new Object() {
#OnProgress(DownloadTask.class)
public void onNiceProgress(#Param(Groundy.PROGRESS) int progress) {
mProgressDialog.setProgress(progress);
}
....
But after obfusecation using proguard the method annotated with "OnProgress" never gets called (but no errors occure)
In the proguard file I added
-keep class com.telly.groundy.*** {
public protected private *;
}
-keepattributes *Annotation*, EnclosingMethod
-keepattributes *OnSuccess*
-keepattributes *OnProgress*
-keepattributes *OnCancel*
-keepattributes *OnCallback*
-keepattributes *OnFailure*
-keepattributes *OnStart*
-keepattributes *Param*
-keepattributes *Traverse*
-keep class com.my.namespace.DownloadTask {
public protected private *;
}
Any idea what "keep" configurations could be missing here ?
I just added a basic proguard configuration to the readme. It looks like this:
-keepattributes *Annotation*
-keepclassmembers,allowobfuscation class * {
#com.telly.groundy.annotations.* *;
<init>();
}
-keepnames class com.telly.groundy.generated.*
-keep class com.telly.groundy.generated.*
-keep class com.telly.groundy.ResultProxy
-keepnames class * extends com.telly.groundy.ResultProxy
-keep class * extends com.telly.groundy.GroundyTask
ProGuard doesn't know that the code accesses the annotation through reflection, so you probably need to preserve it explicitly:
-keep #interface com.telly.groundy.annotations.OnProgress
I am trying to enable ProGuard when compiling my Android application.
Below is the ProGuard configuration.
The problem I have is that I get a lot of warnings about duplicate definition (pretty much for all classes, in my app or the basic java classes) and what's worse is that when I make changes in my code, those do not get reflected when I run on the device.
I am compiling (and developing) using IntelliJ IDEA 11.1.5 (and just enable ProGuard in the project structure, I did not set it to use the system proguard configuration).
I saw that other question, but it does not help at all, I don't think my problem is limited to 3rd party libraries, I imagine it's more about setting the right input/output... ?
-injars bin/classes
-outjars bin/classes-processed.jar
-libraryjars /home/matthieu/android/platforms/android-17/android.jar
-dontpreverify
-repackageclasses ''
-allowaccessmodification
-optimizations !code/simplification/arithmetic
-keepattributes *Annotation*,SourceFile,LineNumberTable,*Annotation*
-renamesourcefileattribute SourceFile
-dontwarn java.awt.**,javax.security.**,java.beans.**,com.sun.**
-keep public class my.package.MainMenuActivity
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context,android.util.AttributeSet);
public <init>(android.content.Context,android.util.AttributeSet,int);
public void set*(...);
}
-keep public class * extends android.view.ViewGroup
-keep public class * extends android.support.v4.app.Fragment
-keep class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }
-keep class com.actionbarsherlock.** { *; }
-keep interface com.actionbarsherlock.** { *; }
-keepclasseswithmembers class * {
public <init>(android.content.Context,android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context,android.util.AttributeSet,int);
}
-keepclassmembers class * extends android.os.Parcelable {
static android.os.Parcelable$Creator CREATOR;
}
-keepclassmembers class **.R$* {
public static <fields>;
}
#ACRA specifics
# keep this class so that logging will show 'ACRA' and not a obfuscated name like 'a'.
# Note: if you are removing log messages elsewhere in this file then this isn't necessary
-keep class org.acra.ACRA {
*;
}
# keep this around for some enums that ACRA needs
-keep class org.acra.ReportingInteractionMode {
*;
}
-keepnames class org.acra.sender.HttpSender$** {
*;
}
-keepnames class org.acra.ReportField {
*;
}
# keep this otherwise it is removed by ProGuard
-keep public class org.acra.ErrorReporter
{
public void addCustomData(java.lang.String,java.lang.String);
public void putCustomData(java.lang.String,java.lang.String);
public void removeCustomData(java.lang.String);
}
# keep this otherwise it is removed by ProGuard
-keep public class org.acra.ErrorReporter
{
public void handleSilentException(java.lang.Throwable);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
Assuming you are building with Ant inside IntelliJ IDEA, you mustn't add -injars, -outjars, or -libraryjars options; the Ant script already does that for you. This explains the warnings about duplicates.
Note that it's better to remove the generic part of the configuration in your proguard-project.txt and rely on the configuration of the Android SDK. The latter is partly generated by aapt (tuned for your project) and partly maintained inside the SDK.