I am trying to build (release) an app and the app crashes due to the fact that there are generated methods that are being obfuscated by ProGuard. How can I ignore all of them in the release build?
I have tried to add the following in the proguard-rules.pro:
-keep public class !*Service_Impl.kt
but seems that it doesnt work. The classes that I want to ignore are named as
C1Service_Impl
C2Service_Impl
and so on and so forth, located in the generated java folder
com.application.myapp.persistence.services.C1Service
com.application.myapp.persistence.services.C2Service
Thanks in advance.
Related
play-services-base-16.0.1.aar (mvnrepository) has proguard.txt with following content:
# b/35135904 Ensure that proguard will not strip the mResultGuardian.
-keepclassmembers class com.google.android.gms.common.api.internal.BasePendingResult {
com.google.android.gms.common.api.internal.BasePendingResult$ReleasableResultGuardian mResultGuardian;
}
But you can see in classes.jar that type of mResultGuardian is already obfuscated to BasePendingResult.zaa. I guess that is why I get
Note: the configuration refers to the unknown class 'com.google.android.gms.common.api.internal.BasePendingResult$ReleasableResultGuardian'
How that's supposed to work? I'm new to Proguard and only have very basic understanding of what is going on so please make your answers simple :)
Project details:
gradlew version: 5.4
build plugin: com.android.tools.build:gradle:3.2.0
Unfortunatelly I can't update gradle build plugin to 3.3.* or 3.4.* right now because some of the scripts are incompatible and would require significant refactoring.
app/proguard.txt (from recommendations I've seen):
-keep class com.google.android.gms.analytics.** { *; }
-keep class com.google.android.gms.gcm.** { *; }
-dontwarn com.google.android.gms.**
But that doesn't help.
UPD
I end up upgrading to com.android.tools.build:gradle:3.4.1 (some api changes had to be adapted) which fixed the issue but I still don't get how that's supposed to work with rules like that.
“If the proguard set up in your project it does some jobs for us in the built process : Minification, obfuscation, repackaging and optimisation. Enabling it is straightforward if you’re using gradle, just set minifyEnabled to true for your release buildType in build.gradle and pass the default set of android optimisation rules.
This will help to shrink, speed up and protect your app. However it mainly works by removing code that is never called and renaming what’s left. This is all well and good until you encounter reflection.
Reflection lets you write code that can look up and execute other code based on its name (among other things)”
“You can also use ProGuard if you or any of the libraries in your app use reflection, here you specify rules as to which classes, methods and other parts of your app ProGuard should leave alone. You can list all these rules in a file and pass them to ProGuard via the proguardFiles method back in your build.gradle. The general convention is for this file to be called proguard-rules.pro”
These doc1, doc2 provide you more information on how to work with rules
I have an issue which I'm pretty sure is related to multidex. Basically one of the libraries I use has a .properties resource bundle in a jar. As my application started growing I started having issues with it. I've made a couple of posts about it in the past but never had any solutions (post 1, post 2). Post 2 actually has a lot more details about the issue.
Basically this resource is missing unless I force some of the code on that Jar to run on the Application onCreate method. At least that was the issue until yesterday.
Yesterday I update a jar that has nothing to do with this but is now larger than it used to be (which I'm assuming means it has more methods), and now the code fails again on this same issue java.util.MissingResourceException: Can't find bundle for base name javax.servlet.LocalStrings, locale en_US but now it fails for everyone, not just some users.
I took apart the apks using apktool for one that works and one that doesn't (basically downgrading those unrelated jars) and there is an unknown folder in both apks but the one that works has those LocalStrings.properties in that folder and the one that doesn't work doesn't have them in that folder. I have unzipped those unrelated jars just to make sure and they don't have that javax.servlet package in there and they are jars so they don't have anything else that might affect the gradle build.
Basically my theory right now is that those jars are just large enough to push the javax.servlet stuff out of the first dex file, but that isn't entirely right because the properties files don't even go in the dex file. If I just unzip the apk, I can see the javax package on the root folder and the resource files inside the right place but not LocalStrings.properties whereas if I do that for an apk that works, I can see LocalStrings.properties in there.
Right now I've been testing multiDexKeepProguard and I got all javax.servlet to go in the main dex file but I still can't get LocalStrings.properties to show up in the apk, even with:
-keepclassmembers class **$Properties
I've also tried a few other crazy things like putting the LocalStrings.properties files inside my main app package using the javax.servlet package and it didn't help either.
So what else can I try? Is this a bug or am I doing something wrong?
Thanks.
Edit: I would like to report that I've once again gotten past this issue by removing a dependency (an ad network) that I'm no longer using. I realized I still had that dependency when I used dex2smali to look at the first dex file and saw it was there. So it definitely appears to be an issue with the size of the jars it puts on the first dex file.
Edit: I have this on my proguard settings:
-keep class javax.** {*;}
-keep interface javax.** {*;}
-keepclassmembers class javax.** {*;}
-keepclassmembers class **$Properties
Not sure if this was the right way to do it, but apparently proguard was mistakenly deleting the *.properties files for me.
What fixed it was doing a build with
minifyEnabled false
and then going back to
minifyEnabled true
After that, the *.properties files were all available in the final build again.
It looks like your package property file is stripped by ProGuard. I am not sure whether you have tried below configurations
-keep class javax.servlet.**
or
-keep class javax.servlet.** { *; }
or
-optimizations !javax.servlet
-dontoptimize
Also, more additional references:
shrink-code: https://developer.android.com/studio/build/shrink-code
Processing resource files: https://docs.huihoo.com/proguard/manual/examples.html
-keeppackagenames https://stackoverflow.com/a/5866755/8034839
How to tell ProGuard to keep everything in a particular package?
I enabled Proguard for my app and now when I get an exception, in Android Monitor I'm seeing something like
at com.mydomain.myapp.v.c(SourceFile:901)
at com.mydomain.myapp.v.a(SourceFile:1260)
In another app that I have, I also have proguard available, but I'm seeing something like
at com.mydomain.myotherapp.v.c(MainMenuScreen.java:948)
and I can click on the class name and Android Studio takes me to the exact line. I've tried copying the entire contents of the proguard file to the first app and nothing changes.
What is the setting in my project that makes Android Monitor have nice clickable links? In my proguard rules I have:
-keepattributes Exceptions, InnerClasses,
Signature, Deprecated, SourceFile, EnclosingMethod, LineNumberTable
There is a reason why you run proguard and obfuscate the code, that reason is not being able to do that! Else it would totally dismiss the point of obfuscation.
What you can do is to fetch your mapping.txt that is in your outputs folder and with the help of proguardgui.bat that is somewhere in your sdk folder you can get a normal stacktrace
With tools like dex2jar and jdgui2 it is very easy to inspect the contents of the APK.
We are trying to use Proguard in our Cordova project to "protect" a few classes that contain information we want to keep secret (Mainly keys to decrypt some content we try to protect for our client).
We cannot get it right. The app crashes, or it isn't obfuscated.
We added to our build.gradle :
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
Our proguard.pro contains:
-keep class !com.smartmobilesoftware.** ( *; }
smartmobilesoftware is an inAppPurchases plugin.
In that package we modified a few classes, which works great without proguard.
I found the following "Proguard support missing": https://issues.apache.org/jira/browse/CB-9269
Here Joe Bowser claims the following: "OK, you shouldn't use ProGuard with Cordova, or at least, there's no good reason to use it, since you can't use it with minifyEnabled, which is what actually makes ProGuard work properly. Since Cordova uses Reflection all over the place, this is a good way to blow up Cordova without a proguard-rules.pro file."
We tried to avoid that issue by telling proguard that ALL classes should be left intact except the ones in the com.smartmobilesoftware (-keep class !com.smartmobilesoftware.** ( *; })
I am not sure if this is a problem witih our code (but the code works fine without proguard), the plugin, or proguard itself.
We do not see any meaningful errors.
We released apps before built with Cordova 2.2.0, which used ANT and proguard and another plugin, which worked fine. So we wonder if Cordove is changed in respect to proguard.
Can anybody maybe shed some light on this issue?
It looks like the code in package com.smartmobilesoftware implements a Cordova plugin. In this case you need to keep at least a few more classes, otherwise Cordova will not properly find them at runtime (for a recent Cordova release):
-keep class * extends org.apache.cordova.CordovaPlugin
Cordova application will crash after obfuscation because of the main activity and cordova classes will get obfuscate. So at runtime failed to create the webview and application will crash.
To resolve this you have to add :
-keep class org.apache.cordova.** {
*;
}
-keep public class * extends org.apache.cordova.CordovaPlugin
There's a nice cordova plugin for this nowadays
https://github.com/greybax/cordova-plugin-proguard
This worked out of the box for me, although I had to add this line to prevent building errors:
-dontwarn com.google.android.gms.**
#Erwin Moller For this issue you may need to safe as less as possible files filter from obfuscation so here you can try below proguard rules and try it too run. Good luck
-keep class org.apache.cordova.engine.** { *; }
-keep public class * extends org.apache.cordova.CordovaPlugin
I have written a java library that I don't want users to be able to see the source code. Hence I used proguard to obfuscated by java library into debug and release AAR. I'm trying to test the obfuscation in a demo project by importing it as an AAR file. When I import the release AAR file, everything is obfuscated and I'm not even able to resolve the symbols.
Is there any way I can obfuscate the source code but allow the AAR to be imported into another project? Similar to a static library/framework in iOS.
Thanks
You have to make sure to keep the class names and methods 'as is' for those classes that are accessed externally by apps using your library.
For example, to keep all public methods and variables declared by a class used by outside apps, add the following to your proguard-project.txt file:
-keep public class com.your.class {public *;}
See here for more information.