I'm Using FCM with Dexguard.
FCM cannot make token in release build.
but, it works well in debug build.
my gradle settings
classpath 'com.google.gms:google-services:3.2.1'
compile 'com.google.android.gms:play-services-base:15.0.2'
compile 'com.google.android.gms:play-services-analytics:15.0.2'
compile 'com.google.firebase:firebase-core:15.0.2'
compile 'com.google.firebase:firebase-messaging:15.0.2'
And, ShrinkResources = false And optimize 5time by Dexguard
gradle version : 4.1
android gradle plugin : 2.3.3
options in dexguardFile related with FCM
-keep public class com.google.firebase.** { *; }
-keep public class com.google.firebase.iid.FirebaseInstanceId { public *;}
Firebase 15+ requires some additional rules. The latest DexGuard version 8.2.09 for example includes all necessary configurations.
Add the following dexguard rules to fix the problem:
-keep class com.google.firebase** { *; }
-dontshrink
It seems that dexguard removes all classes that are not directly referenced in code. So the entry points like services classes to get firebase tokens (FirebaseInstanceIdService) will be removed during obfuscation process, if shrinking is allowed.
I had similar issues with Firebase analytics where it works for debug build but not the release build, thanks to T. Neidhart's answer above I found this block from the Dexguard 8.4.13 sample - samples/advanced/GooglePlayServices/AdMob/dexguard-project.txt and it solves the problem for me.
-keep public class !**.internal.**, com.google.** {
public protected *;
}
# We can repackage all obfuscated classes in a new internal package.
-repackageclasses com.google.internal
Related
i get this message error when i build my app in release mode.
No pending exception expected: java.lang.NoSuchFieldError: no "Ljava/lang/String;" field "amplitudes" in class "Llinc/com/amplituda/AmplitudaResultJNI;" or its superclasses.
But app correctly works on Dev build. What should i do?
gradle file
implementation 'com.github.lincollincol:amplituda:2.1.2'
proguard-rules.pro
-keep class linc.com.amplituda.** { *; }
Thanks
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.**,**
When invoking FirebaseFunctions.getInstance(FirebaseApp.getInstance()) an NPE is thrown. FirebaseApp.initializeApp(this); is called inside extended App class onCreate before calling any other firebase functionality.
This is the stacktrace:
Fatal Exception: java.lang.NullPointerException
at com.google.firebase.functions.internal.Preconditions.checkNotNull(Unknown Source:876)
at com.google.firebase.functions.FirebaseFunctions.<init>(Unknown Source:77)
at com.google.firebase.functions.FirebaseFunctions.getInstance(Unknown Source:141)
at com.google.firebase.functions.FirebaseFunctions.getInstance(Unknown Source:159)
The exception is thrown only when building the application with release configuration, this means the code gets obfuscated with DexGuard but all firebase classes have been excluded from the obfuscation, below my dexguard config:
...
-keep class com.google.** { *; }
-keep class android.** { *; }
-keep class com.firebase.** { *; }
-keep class com.android.** { *; }
...
I'm using:
com.google.firebase:firebase-functions:12.0.1 (also all other firebase libraries use the same version)
DexGuard version 8.1.15
classpath 'com.google.gms:google-services:4.0.1'
When using debug configuration everything works like charm, any idea how to solve this?
Already checked this similar question but it's outdated: Error with Firebase callable functions
EDIT - New configuration
I tried updating both DexGuard dependency and Firebase one with the ones below:
com.google.firebase:firebase-functions:16.1.1 (all other firebase and gms dependencies are updated to the latest one, except for play-services-ads that is 16.0.0)
DexGuard version 8.2.20
classpath 'com.google.gms:google-services:4.0.1'
This is the new stacktrace:
Fatal Exception: java.lang.NullPointerException: null reference
at com.google.firebase.functions.a.a.a(Unknown Source:30)
at com.google.firebase.functions.FirebaseFunctions.(Unknown Source:77)
at com.google.firebase.functions.FirebaseFunctions.getInstance(Unknown Source:141)
at com.google.firebase.functions.FirebaseFunctions.getInstance(Unknown Source:154)
For the ones who may face the same problem, it was caused by the "projectId" field being null when the FirebaseOptions were initialised by the sdk using FirebaseOptions.fromResource(Context) and the app was protected with DexGuard
FirebaseOptions {
applicationId = ***********************,
apiKeyapiKey = ***********************,
databaseUrl = ***********************,
gcmSenderId = ***********************,
storageBucket = ***********************,
projectId = null
}
The problem has been solved by adding the following line to the DexGuard config file:
-keepresources string/project_id
I'm updating our project to use Gradle 4.1 and Android Gradle plugin 3.0.1. I have updated our dependency configuration to the new configuration and the project successfully compiles. However, there are lots of unresolved dependencies (incl. Kotlin standard library's top-level functions) when compiling android tests (assembleAndroidTest Gradle task). I was suspecting that Proguard might cause this (although it didn't before updating Gradle), but even adding explicit rules to keep symbols/classes doesn't help. We use Kotlin 1.2.10 and Kotlin-Kapt plugin.
I appreciate any help.
I don't use ProGuard for debug but the following answers seem useful.
I would revise your Gradle configuration another time following the migration guide, and first of all clean and invalidate caches.
Proguard
Chech this question and answers about how to use Kotlin with Proguard.
Disable these directives in your build.gradle file to discard Proguard.
minifyEnabled false
shrinkResources false
Configure Proguard for Kotlin.
You don't need to do anything special. Kotlin works with ProGuard out
of the box. But you may face some strange errors when processing your
application with ProGuard. In this case just add:
-dontwarn kotlin.**
You also can add:
-keep class kotlin.** { *; }
-keep class kotlin.Metadata { *; }
-dontwarn kotlin.**
-keepclassmembers class **$WhenMappings {
<fields>;
}
-keepclassmembers class kotlin.Metadata {
public <methods>;
}
-assumenosideeffects class kotlin.jvm.internal.Intrinsics {
static void checkParameterIsNotNull(java.lang.Object, java.lang.String);
}
Check this related questions to either enable Proguard for tests or not:
proguard gradle debug build but not the tests
Specify the Proguard file to use on the instrumentation tests.
runProguard is old. It was replaced with minifyEnabled
With minifyEnabled (and other changes in new versions of Gradle) you
will may encounter issues where the Proguard config works for your
debug apk but not for the instrumentation tests. The apk created for
instrumentation tests will use its own proguard file, so changing your
existing proguard file will have no effect.
In this case, you need to specify the proguard file to use on the
instrumentation tests. It can be quite permissive because it's not
affecting your debug and release builds at all.
// inside android block
debug {
shrinkResources true // removes unused graphics etc
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
testProguardFile('test-proguard-rules.pro')
}
Android Unit Tests with proguard enabled
Add a custom proguard rules file
/project/app/proguard-test-rules.pro
# Proguard rules that are applied to your test apk/code.
-ignorewarnings
-keepattributes *Annotation*
-dontnote junit.framework.**
-dontnote junit.runner.**
-dontwarn android.test.**
-dontwarn android.support.test.**
-dontwarn org.junit.**
-dontwarn org.hamcrest.**
-dontwarn com.squareup.javawriter.JavaWriter
# Uncomment this if you use Mockito
#-dontwarn org.mockito.**
The add the following to your build.gradle for your app. To use the proguard file when testing.
/project/app/build.gradle
android {
debug {
minifyEnabled true
testProguardFile 'proguard-test-rules.pro'
}
}
Add a buidType for testing
I've solved this problem in my build by having an additional "dev"
buildType where I enable proguard, but configure it to keep all code
in my own package, and a few specific library classes that happen to
be used from tests only. I also disable obfuscation in the dev
buildType so that it can be debugged from an IDE.
For debug and release builds I use my "real" proguard settings
including obfuscation and optimizations.
Use separate test modules
Separate test modules are now variant-aware. This means that
specifying targetVariant is no longer necessary.
Each variant in the test module will attempt to test a matching
variant in the target project. By default, test modules contain only a
debug variant, but you can create new build types and new flavors to
create new variants to match the tested app project. A connectedCheck
task is created for each variant.
To make the test module test a different build type only, and not the
debug one, use VariantFilter to disable the debug variant in the test
project, as shown below:
android {
variantFilter { variant ->
if (variant.buildType.name.equals('debug')) {
variant.setIgnore(true);
}
}
}
If you want a test module to target only certain flavors or build
types of an app, you can use the matchingFallbacks property to target
only the variants you want to test. This also prevents the test module
from having to configure those variants for itself.
Gradle
Revise your Gradle configuration. In order to to build an Android project written in Kotlin:
Set up the kotlin-android gradle plugin and apply it to your project.
Add kotlin-stdlib dependencies.
Those actions may also be performed automatically in IntelliJ IDEA /
AS by invoking the action:
Tools | Kotlin | Configure Kotlin in Project
kotlin-android
buildscript {
ext.kotlin_version = '1.2.10'
...
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
kotlin-stdlib
Don't forget to configure the standard library dependency:
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib"
}
Revise your dependencies configuration using the migration
guide.
Note: compile, provided, and apk are currently still available.
However, they will be removed in the next major release of
the Android plugin.
Provide version manually
Starting with Kotlin 1.1.2, the dependencies with group
org.jetbrains.kotlin are by default resolved with the version taken
from the applied plugin.
You can provide the version manually using the full dependency
notation like this:
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
Resolution strategy
You also can force the resolution strategy:
configurations.all {
resolutionStrategy {
force "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
}
As you are using Android Gradle plugin 3.0.1:
// Instead, because the new build model delays dependency resolution, you
// should query and modify the resolution strategy using the Variant API:
android {
applicationVariants.all { variant ->
variant.getCompileConfiguration().resolutionStrategy {
...
}
variant.runtimeConfiguration.resolutionStrategy {
...
}
variant.getAnnotationProcessorConfiguration().resolutionStrategy {
...
}
}
}
Exclude app dependencies from test configurations using the Variant API:
On previous versions of the Android plugin, you could exclude certain
transitive dependencies of your app from your tests using the exclude
keyword. However, with the new dependency configurations, you must do
it at execution time using the Variant API:
android.testVariants.all { variant ->
variant.getCompileConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp'
variant.getRuntimeConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp'
}
Extended versions of the Kotlin standard library
If you're targeting JDK 7 or JDK 8, you can use extended versions of
the Kotlin standard library which contain additional extension
functions for APIs added in new JDK versions. Instead of
kotlin-stdlib, use one of the following dependencies:
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7"
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
In Kotlin 1.1.x, use kotlin-stdlib-jre7 and kotlin-stdlib-jre8
instead.
Kotlin reflection
If your project uses Kotlin
reflection
or testing facilities, you need to add the corresponding dependencies
as well:
compile "org.jetbrains.kotlin:kotlin-reflect"
testCompile "org.jetbrains.kotlin:kotlin-test"
testCompile "org.jetbrains.kotlin:kotlin-test-junit"
Kapt
See the description of Kotlin annotation processing tool (kapt).
Apply the kotlin-kapt Gradle plugin:
apply plugin: 'kotlin-kapt'
I have the classes.jar from Unity3d included in my libs folder of Project in Android Studio.
If i enable proguard, i could not build it.
minifyEnabled true
my build.grade got dependencies
dependencies {
compile 'com.google.android.gms:play-services:+'
compile files('libs/classes.jar')
}
proguard-rules file has
-dontwarn org.fmod.**
-keep class com.unity3d.** { *; }
-keep class org.fmod.** { *; }
-keepclassmembers class com.unity3d.player.** { *; }
-keepclassmembers class org.fmod.** { *; }
-libraryjars !libs/classes.jar(!org/fmod/FMODAudioDevice.class)
check the proguard website to have -libraryjars with !. Did not help as well.
Following is the build error.
Error:Execution failed for task ':Android:proguardRelease'.
java.io.IOException: Can't read [/Users/me/after_android_studio/src/libs/classes.jar(;;;;;;!META-INF/MANIFEST.MF)] (Can't process class [org/fmod/FMODAudioDevice.class] (256))
I did my search for similar issue. But i could not read the following URLs.
unresolvedlibraryclassmember
http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedclass
http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedlibraryclassmember
Check that the jar file is not strange or corrupt in some way. I came across your question while dealing with the same error message, but for a different jar file. I just discovered that the jar I was fighting with contained a directory entry named "VCardProvider.class". Since it was actually a directory, ProGuard failed to read the ".class" file. Perhaps ProGuard shouldn't have failed (it isn't a file, after all), but fixing the jar resolved the issue for me.