How to fix Proguard issue with Google Drive REST API - android

I'm using the Google Rest API v3 to connect my android app to Google Drive. When I run without Proguard (minifyEnabled=false), all is well. However, when I enable proguard the wrong REST API methods are called. When I call Drive.Files.get().execute on the drive root alias "root" I get the result for a Drive.Files.list().execute. When I disable "minifyEnabled" I see the correct result. Here is the section of the build.gradle that controls running Proguard:
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
The default Proguard file is the unmodified one that gets distributes with Android Studio 2.2 (not the optimized version)
And this is the contents of my proguard-rules.pro file
-keepattributes EnclosingMethod
-keepattributes InnerClasses
-dontoptimize
-keep class com.google.**
-keep class com.fasterxml.**
-dontwarn com.google.**
When I check in the generated mapping.txt I still see renamed members in classes that imo shoudl have been "kept". For example:
com.google.api.client.auth.oauth.OAuthParameters -> com.google.api.client.auth.oauth.OAuthParameters:
java.security.SecureRandom RANDOM -> l
com.google.api.client.auth.oauth.OAuthSigner signer -> a
java.lang.String callback -> b
java.lang.String consumerKey -> c
java.lang.String nonce -> d
java.lang.String realm -> e
I would have thought "-keep class com.google.** " would have avoided this?
Any idea how to fix this?
THanks in advance,

This one worked for me:
-keepclassmembers class * {
#com.google.api.client.util.Key <fields>;
}
As seen in the official google sample:
https://github.com/google/google-api-java-client-samples/blob/master/tasks-android-sample/proguard-google-api-client.txt

You need
-keep class com.google.** { *;}
and
-keep class com.fasterxml.** { *;}
Also you might try to keep less from the SDK. These rules are very wide.
Edit:
Wide rules means that it probably will keep more unused classes in your project hence the apk size and method count will be bigger.

In my case I had to put these keeps:
-keep class br.project.pine.** { *;}
-keep class com.google.api.services.drive.** { *;}
Tip: When enabling minify in debug mode, pay attention to the LogCat. It can help you to find out the real missing package/class/attribute.

Related

Retrofit2 not working when enabling Proguard

I have an application which uses retrofit to fetch logo form an API.
When i don't obfuscate and shrink my code, everything works fine. But when i enable it, the API call stops working. I don't get any crash or error messages, i just don't get any values from the API.
gradle
buildTypes {
debug{
// Enables code shrinking, obfuscation, and optimization for only
// your project's release build type.
minifyEnabled true
// Enables resource shrinking, which is performed by the
// Android Gradle plugin.
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
}
release {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
I used it in debug just for testing purposes. If i use it in release, it has same output.
I checked the retrofit page and they advised to use the following file
proguard-rules.pro
# Uncomment this to preserve the line number information for
# debugging stack traces.
-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
-renamesourcefileattribute SourceFile
-printusage usage.txt
-keep class com.th3pl4gu3.locky_offline.core.main.** {*;}
-keep class com.th3pl4gu3.locky_offline.repository.network.** {*;}
-keep class com.th3pl4gu3.locky_offline.repository.database.** {*;}
# Retrofit does reflection on generic parameters. InnerClasses is required to use Signature and
# EnclosingMethod is required to use InnerClasses.
-keepattributes Signature, InnerClasses, EnclosingMethod
# Retrofit does reflection on method and parameter annotations.
-keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations
# Retain service method parameters when optimizing.
-keepclassmembers,allowshrinking,allowobfuscation interface * {
#retrofit2.http.* <methods>;
}
# Ignore annotation used for build tooling.
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
# Ignore JSR 305 annotations for embedding nullability information.
-dontwarn javax.annotation.**
# Guarded by a NoClassDefFoundError try/catch and only used when on the classpath.
-dontwarn kotlin.Unit
# Top-level functions that can only be used by Kotlin.
-dontwarn retrofit2.KotlinExtensions
-dontwarn retrofit2.KotlinExtensions$*
# With R8 full mode, it sees no subtypes of Retrofit interfaces since they are created with a Proxy
# and replaces all potential values with null. Explicitly keeping the interfaces prevents this.
-if interface * { #retrofit2.http.* <methods>; }
-keep,allowobfuscation interface <1>
The API call still doesn't work. I tried many posts on stackoverflow but nothing works for me. Can someone help me by proposing a solution or an alternative to this ?
Thank you
Have you tried to put #SerializedName to Object field?
public class YourJsonClass{
#SerializedName("username")
String username;
}
Use progaurd rules from the official retrofit site
https://github.com/square/retrofit/blob/master/retrofit/src/main/resources/META-INF/proguard/retrofit2.pro
Sometimes issue seems to be from retrofit but it is not. It’s a GSON and ProGuard problem. To fix it you just have to add a -keep class configuration in your proguard rules of the package where your Pojo class is stored For example my API response and request classes are stored like this (package name may differ according to your app):
-keep class com.sample.myapp.model.request. { ; }
-keep class com.sample.myapp.model.model.response.* { ; }*

Proguard (R8) negate operator not working to keep anything except certain packages

The negator (exclamation mark) in proguard should allow me to keep anthing but the apache libraries:
-keep class !org.apache.**
According to those answers. That's the way to go:
How to negate classname with Proguard
Enable Proguard for only two packages in large Android application
Android proguard Ignore All Classes except of one
Proguard Android do not obfuscate anything except few classes
Proguard: How to keep everything except specific condition?
Can we shrink all classes but only obfuscate some with proguard?
However, it obfuscates all classes in my APK.
That's part of my build.gradle (I have Android Studio 3.5.3)
compileSdkVersion 29
buildToolsVersion "29.0.2"
//...
buildTypes {
release {
minifyEnabled true
proguardFiles /*getDefaultProguardFile('proguard-android.txt'),*/ 'proguard-rules.pro'
// Enables resource shrinking, which is performed by the
// Android Gradle plugin.
shrinkResources false
}
}
dependencies {
//Utility libs
implementation 'org.apache.commons:commons-collections4:4.1'
implementation 'org.apache.commons:commons-lang3:3.4'
implementation group: 'commons-io', name: 'commons-io', version: '2.5'
}
After I added -printconfiguration to my proguard-rules.pro file I saw there are numerous -keep rules following my -keep class !org.apache.**
-printconfiguration
-keep class !org.apache.**
# Referenced at ***anonymized***\app\build\intermediates\merged_manifests\release\AndroidManifest.xml:180
-keep class android.support.v4.app.CoreComponentFactory { <init>(); }
# Referenced at ***anonymized***\app\build\intermediates\merged_manifests\release\AndroidManifest.xml:180
-keep class com.mycompany.MyApplication { <init>(); }
# Referenced at C:\Users\***anonymized***\.gradle\caches\transforms-2\files-2.1\7f5f0b3369d8fa8a72a20e2278ec0acc\appcompat-v7-28.0.0\res\layout\abc_action_menu_item_layout.xml:17
-keep class android.support.v7.view.menu.ActionMenuItemView { <init>(...); }
That approach suggested by Ezekiel Baniaga also didn't work. Instead it keeps everything including the apache packages:
proguard-rules.pro
-printconfiguration
-dontshrink
-dontoptimize
-dontobfuscate
-keep,allowshrinking,allowoptimization,allowobfuscation class org.apache.**
I had to add ,** to get it working. Thanks T. Neidhart!
-keep class !org.apache.**,**
The previous example preserved class names but still obfuscated members. So I had to add { *; }:
-keep class !org.apache.**,** { *; }
That's how I obfuscate multiple packages (I have to use them all in one keep rule!)
-keep class !org.apache.**, !org.zeroturnaround.**, !com.drew.**, ** { *; }
To find out what my problem is with -dontshrink -dontoptimize -dontobfuscate -keep,allowshrinking,allowoptimization,allowobfuscation class org.apache.** I could add -whyareyoukeeping according to https://www.guardsquare.com/en/products/proguard/manual/usage
You should file a bug report with the R8 project if this does not work anymore.
In order to keep using Proguard in the meantime, you can add this to your gradle.properties files:
android.enableR8=false
Further tests show that the implicit behavior of ProGuard is not implemented like that in R8.
So a rule like:
-keep class !org.apache.**
will implicitly keep all other classes when using ProGuard, but not when using R8. To achieve the same behavior with R8, change the rule to this:
-keep class !org.apache.**,**

Why is Proguard not obfuscating my code?

When I build a release build of the app Proguard runs, but on looking at the APK using APK Analyzer everything is readable with apparently no obfuscation being applied.
My intent is to apply obfuscation to the APK to make reverse engineering a little more difficult.
Gradle:
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
Proguard is definitely running as I can see that in the Gradle console.
proguard-rules.pro:
-dontshrink
-dontoptimize
-keep class com.squareup.picasso.** { *; }
-dontwarn com.squareup.picasso.**
-keep class com.squareup.okhttp.** { *; }
-dontwarn com.squareup.okhttp.**
-keep class kotlin.reflect.** { *; }
-dontwarn kotlin.reflect.**
-keep class javax.annotation.** { *; }
-dontwarn javax.annotation.**
-keep class org.codehaus.mojo.** { *; }
-dontwarn org.codehaus.mojo.**
The Proguard docs say obfuscation runs by default. The docs also say classes specified in keep statements will not be obfuscated, but the classes in the app itself are not specified in keep statements, but are still not obfuscated.
On looking further, there is a file in the build folder called aapt_rules.txt that contains what look like keep statements for every class in the app. I don't understand why that would be.
How do I reconfigure Proguard so it obfuscates all of the code in my app (not the libraries), without shrinking or removing any classes?
by looking at line keep class com.squareup.picasso.** { *; }and -keep class com.squareup.okhttp.** { *; } ,
you are not obfuscating anything which are part of above packages or sub packages.
Progaurd will obfuscate anything which is not part of above package and sub package.
do you have class outside of these packages.

Runtime issues while using Proguard to minify

My app is completely ready to deploy and its using many libraries. I want to minify the code using Proguard and also want to remove unused classes and resources but while using proguard I am getting Runtime error
java.lang.RuntimeException: Unable to create application com.rig.onblick.App: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.hashCode()' on a null object reference
I gone through many tutorial but its seems too complicated to write proguard configuration because I have to write many rules to make sure my app will run perfectly. I have never used proguard in this kind of big project. Can anyone tell me the minimal configuration which make sure at least my code will be minified and will not get any runtime error.
My present configuration is as below.
-dontwarn com.witt.mspapp.**
-keep class com.github.mikephil.** { *; }
-dontwarn com.github.mikephil.**
-keep class com.github.mikephil.** { *; }
-dontwarn org.apache.**
-keep class com.google.gms.** { *; }
-dontwarn com.google.gms.**
-keep class com.viewpagerindicator.** { *; }
-dontwarn com.viewpagerindicator.**
-keep class org.jivesoftware.smackx.** { *; }
-dontwarn org.jivesoftware.smackx.**
I am testing in debug env. and my gradle configuration is as below
debug {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
There is nothing "minimal configuration" for proguard configuration. You will get the proguard configuration for each library on his official repo page. So whatever dependencies you have used go through these and add proguard configuration for each of that dependency.

App using SimpleXML with minifyEnabled does not work

I have an app that works fine when debugging, but when I make a release version, with minifyEnabled true in the build.gradle file, it seems not to work at all anymore:
D/SapphirePocket( 6520): Could not serialize telegram: <init> [interface a.a.a.b.am, interface a.a.a.a, class a.a.a.e.n]
Does SimpleXML work with minified APKs, where inspection might not completely work anymore or should this just work?
When you activate minifyEnabled, you are obfuscating the code with proguard. SimpleXML should use some classes that you are obfuscating and you must not do this. You must keep the names of the classes that SimpleXML needs.
See this post about the same problem as you have (simplexml failed to compile with proguard activated).
The first thing I recommend is put this on proguard file (extracted from the post I've linked):
-keep public class org.simpleframework.** { *; }
-keep class org.simpleframework.xml.** { *; }
-keep class org.simpleframework.xml.core.** { *; }
-keep class org.simpleframework.xml.util.** { *; }
-keepattributes ElementList, Root
-keepclassmembers class * {
#org.simpleframework.xml.* *;
}
For a more detailed response, please, show us more information (proguard file, code getting the error...).

Categories

Resources