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?
Related
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.
I'm using Proguard to optimize the generated APK. The project is using a 3rd library that has files located in resources folder. The problem is that when i check the generated APK, the files in resources folder is disappeared and cause crashing when i run the application.
Even i remove the shrinkResource from gradle build, the problem is still there. I tried to disable Proguard and everything works fine.
Here is the related Proguard config for the library:
-keep class com.bitmark.apiservice.** {*;}
-keep class com.bitmark.cryptography.** {*;}
-keep class com.bitmark.sdk.** {*;}
I would like to keep the txt files is located inside folder foo but actually it been removed absolutely.
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
I have an Android project with a proguard-rules.pro file for the app module that contains only the following:
# ProGuard rules
-dontobfuscate
-dontwarn android.arch.util.paging.CountedDataSource
-dontwarn android.arch.persistence.room.paging.LimitOffsetDataSource
I am not keeping anything myself. All -keep rules are coming from something else, whether that is the rules provided by getDefaultProguardFile('proguard-android-optimize.txt') or from rules packaged in libraries.
However, stuff is being kept that I am not using. If I use the Android Studio APK Analyzer on my release build, while lots of things are removed by ProGuard, lots of other things are kept that I am not referencing.
For example: through transitive dependencies, I have the Support Library module that contains ViewPager in the app's dependencies tree. However, I am not (presently) using ViewPager in this app. Despite this, something is causing it to be kept, as the APK Analyzer shows 107 defined methods for android.support.v4.view.ViewPager, including its constructor.
I could use various ProGuard options to track down why this is being kept. However, it is not coming from my rules. There is no -keep of my own that needs fixing — the -keep is coming from somebody else, presumably a Google engineer.
So, how do I get rid of ViewPager? Is there a way that I can override the -keep rule that is causing it to be kept (e.g., using allowshrinking)? If so, how does ProGuard, as invoked by Android Studio, determine whose -keep rule wins?
The ViewPager class isn't kept in a small app that I just checked, so it must be other code or other rules in your project indeed.
You can start with letting ProGuard print out the chain that triggers ViewPager to be kept:
-whyareyoukeeping class android.support.v4.view.ViewPager
You may need to repeat this a number of times for various classes and methods to get to the root cause. ProGuard doesn't print out which rule exactly is responsible -- admittedly, this would be a useful feature.
You can then look for the proguard.txt file in build/intermediates/exploded-aar that contains a matching rule.
As for a solution at that point:
It is not possible to override -keep rules; they only accumulate.
As far as I know, the Android Gradle plugin also doesn't support disabling overly conservative proguard.txt files in libraries, so you'd need to create a custom .aar file with the updated rule, or send a suggestion to the developers of the library.
I'm trying to build an Android release with Ant and ProGuard. I uncommented the following line in project.properties, despite the comment in said file noting that you shouldn't modify it ;):
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
When obfuscating, I get the following notes:
[proguard] Note: the configuration refers to the unknown class 'com.google.vending.licensing.ILicensingService'
[proguard] Note: the configuration refers to the unknown class 'com.android.vending.licensing.ILicensingService'
I do understand why this is happening. These lines can be found in the default ProGuard config file (${sdk.dir}/tools/proguard/proguard-android.txt):
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService
I'm not using the Google Licensing Service, so the classes are indeed unknown. I found a solution to get rid of these notes by updating the proguard-project.txt:
-dontnote **ILicensingService
My question: Is this the correct way of handling this? It seems to me that these classes shouldn't be kept by default anyway, since that lib isn't mandatory for an android project. The only way I can think of to achieve this is by copying the default config file to my project, removing the -keep lines and ignoring the default config file in the SDK completely. Which doesn't seem as the proper way to go either. Or am I missing something?
The setting "-dontnote com.google.vending.licensing.ILicensingService" is fine. In fact, it could have been part of the default configuration file.
The -keep option may be necessary for projects that use the library.
The -dontnote option may be nice to suppress the note about the -keep option, for projects that don't use the library. The note is just a gentle reminder that the configuration file could contain a typo, because the specified class doesn't seem to exist. It doesn't affect the processing.