How to configure Proguard so that obfuscation works without code optimization? - proguard

Only obfuscation is needed. Settings in build.gradle:
debug {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
Found that the -dontoptimize parameter is responsible for optimization. Added it to proguard-rules.pro. just a line:
-dontoptimize
It didn’t work, maybe the flag was added incorrectly?

Related

Task :app:validateSigningRelease FAILED (not found for signing config 'release'.) using react native

what can i do when keystore is already available in my app but error is coming like this (not found for signing config 'release'.)????? using react native
Task :app:validateSigningRelease FAILED
If you followed the steps of the official docs for releasing signed APK's it should work correctly.
Without any code is hard, but off the top of my head I think your problem may be on your app/build.gradle (android -> app -> build.gradle
In this code section you should have the following if you are going to release:
buildTypes {
debug {
signingConfig signingConfigs.debug
}
release {
// Caution! In production, you need to generate your own keystore file.
// see https://facebook.github.io/react-native/docs/signed-apk-android.
signingConfig signingConfigs.release
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}
Notice that in realease -> signingConfig the configuration is signingConfigs.release

React-Native Android Build Failure: Execution failed for task ':app:processDebugResources'. Failed to process resources

I cannot figure out what is wrong with the build. I tried the common solutions of running ./gradlew clean as well as adding the android.enableAapt2=false to the gradle.properties.
The google-services.json folder is at the /android/app level.
Im at a loss right now as to how to get past this one.
If I forgot to include something useful please lmk and I will update.
Cheers
Error Output
Configure project :app
WARNING: The specified Android SDK Build Tools version (26.0.1) is ignored, as it is below the minimum supported version (27.0.3) for Android Gradle Plugin 3.1.3.
Android SDK Build Tools 27.0.3 will be used.
To suppress this warning, remove "buildToolsVersion '26.0.1'" from your build.gradle file, as each version of the Android Gradle Plugin now has a default version of the build tools.
Could not find google-services.json while looking in [src/nullnull/debug, src/debug/nullnull, src/nullnull, src/debug, src/nullnullDebug]
registerResGeneratingTask is deprecated, use registerGeneratedResFolders(FileCollection)
Could not find google-services.json while looking in [src/nullnull/release, src/release/nullnull, src/nullnull, src/release, src/nullnullRelease]
registerResGeneratingTask is deprecated, use registerGeneratedResFolders(FileCollection)
Configure project :react-native-google-analytics-bridge
WARNING: Configuration 'compile' is obsolete and has been replaced with 'implementation' and 'api'.
It will be removed at the end of 2018. For more information see: http://d.android.com/r/tools/update-dependency-configurations.html
Configure project :react-native-radar
WARNING: Configuration 'compile' is obsolete and has been replaced with 'implementation' and 'api'.
It will be removed at the end of 2018. For more information see: http://d.android.com/r/tools/update-dependency-configurations.html
Task :app:processDebugGoogleServices
Parsing json file: /Users/kyletreman/18F/courier_test_app/android/app/google-services.json
/Users/kyletreman/.gradle/caches/transforms-1/files-1.1/appcompat-v7-23.0.1.aar/64df69838d7c555de168bdcf18f3be5c/res/values/values.xml:113:5-69: AAPT: error: resource android:attr/fontVariationSettings not found.
/Users/kyletreman/.gradle/caches/transforms-1/files-1.1/appcompat-v7-23.0.1.aar/64df69838d7c555de168bdcf18f3be5c/res/values/values.xml:113:5-69: AAPT: error: resource android:attr/ttcIndex not found.
error: failed linking references.
FAILURE: Build failed with an exception.
What went wrong:
Execution failed for task ':app:processDebugResources'.
Failed to process resources, see aapt output above for details.
Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
Get more help at https://help.gradle.org
BUILD FAILED in 2s
50 actionable tasks: 3 executed, 47 up-to-date
Could not install the app on the device, read the error above for details.
Make sure you have an Android emulator running or a device connected and have
set up your Android development environment:
https://facebook.github.io/react-native/docs/getting-started.html
/android/app/build.gradle
android {
compileSdkVersion 27
buildToolsVersion "27.0.3"
defaultConfig {
applicationId "com.courier_test_app.app"
minSdkVersion 16
targetSdkVersion 27
versionCode 1
versionName "1.0"
ndk {
abiFilters "armeabi-v7a", "x86"
}
}
splits {
abi {
reset()
enable enableSeparateBuildPerCPUArchitecture
universalApk false // If true, also generate a universal APK
include "armeabi-v7a", "x86"
}
}
buildTypes {
release {
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}
// applicationVariants are e.g. debug, release
applicationVariants.all { variant ->
variant.outputs.each { output ->
// For each separate APK per architecture, set a unique version code as described here:
// http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
def versionCodes = ["armeabi-v7a":1, "x86":2]
def abi = output.getFilter(OutputFile.ABI)
if (abi != null) { // null for the universal-debug, universal-release variants
output.versionCodeOverride =
versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
}
}
}
}
dependencies {
implementation(project(':react-native-firebase')) {
transitive = false
}
implementation 'com.google.firebase:firebase-core:16.0.0'
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation 'com.android.support:support-v13:27.1.1'
implementation "com.facebook.react:react-native:+" // From node_modules
implementation project(':react-native-radar')
implementation project(':react-native-google-analytics-bridge')
}
// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
from configurations.compile
into 'libs'
}
apply plugin: 'com.google.gms.google-services'
com.google.gms.googleservices.GoogleServicesPlugin.config.disableVersionCheck = true
/android/build.gradle
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.google.gms:google-services:4.0.0'
classpath 'com.android.tools.build:gradle:3.1.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
mavenLocal()
google()
jcenter()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
}
}
configurations.all {
resolutionStrategy {
force 'com.android.support:support-v4:27.1.0'
}
}
From the error log I can see that appcompat-v7-23.0.1 is still being used. So, it would probably help to update resolutionStrategy:
configurations.all {
resolutionStrategy {
force 'com.android.support:support-v4:27.1.0'
force 'com.android.support:appcompat-v7-23.0.1'
}
}
Also you need to place that resolution strategy block in your app/build.gradle
Fixed
I was able to get help from someone familiar with the native side and he helped me sort out quite a few errors.
implementation order matters, this was the order that worked for me
implementation "com.facebook.react:react-native:+" // From node_modules
implementation "com.android.support:support-v4:27.1.1"
implementation 'com.android.support:support-v13:27.1.1'
implementation "com.android.support:appcompat-v7:27.1.1"
implementation(project(':react-native-firebase'))
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation project(':react-native-radar')
implementation project(':react-native-google-analytics-bridge')
I need to move the configuration resolution strategies to the android/app/build.gradle file, mine were at the wrong level. I also had to alter versions of the support and appcompat packages. You can find dependencies via
./gradlew app:dependencies
from the android folder. The issue was one of the dependencies was pulling a older version, which was fixed by using the following in the resolutionStrategies.
force 'com.android.support:appcompat-v7:27.1.1'
The next change that needed to be made was the following line in the MainApplication.java
return BuildConfig.DEBUG;
to this
return <app_name>.BuildConfig.DEBUG;
I also removed the enableaapt2=false
The last tip I can give is that naming matters, don't rename your app unless its absolutely necessary and make sure it changes across the Main java files and AndroidMainfest.xml.
UPDATED
I realized my debugger was not connecting, it was because I removed some implementation packages that supported firebase, adding them back fixed the issue. Add the following below the firebase implementation.
implementation "com.google.android.gms:play-services-base:15.0.1"
implementation "com.google.firebase:firebase-core:16.0.1"
put this code at the end of android/build.gradle
use your own numbers for the compileSdkVersion and buildToolsVersion
subprojects {
afterEvaluate {project ->
if (project.hasProperty("android")) {
android {
compileSdkVersion 27
buildToolsVersion "27.0.2"
}
}
}
}

React Native CodePush different key for the 'Production' deployment

My app is linked with the 'Staging' deployment key 'sss'. It's defined at /android/app/src/main/res/values/strings.xml, under reactNativeCodePush_androidDeploymentKey.
Now when I actually release an APK, I'd like to use the 'Production' deployment key 'ppp'.
What's the best way to do that? How do I automate it, so it knows it should use the 'ppp' key? I use the ./gradlew assembleRelease command to build the APK.
The standard way to do this would be to use a build type resource override.
If your build types are debug and release, you would put a strings.xml file at /android/app/src/release/res/values/strings.xml with only the one key reactNativeCodePush_androidDeploymentKey with a value of ppp
Another possible way to do this, if you didn't want to commit your prod key to your repo would be to place it in an environment variable.
Your Gradle file would have to read the env var:
def codePushKey = System.getenv("CODEPUSH_KEY") ?: "sss"
Add the env var to your BuildConfig dynamically
buildTypes {
release {
minifyEnabled true
debuggable false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.config
buildConfigField "String", "CODEPUSH_KEY", codePushKey
}
Replace your CodePush instantiation with the BuildConfig var instead of a string resource.
In your ReactNativeHost implementation, in the getPackages() override, update the CodePush instantiation to:
new CodePush(BuildConfig.CODEPUSH_KEY, getApplicationContext(), BuildConfig.DEBUG)

Update a Mobilefirst 8.0 Proguard application

I want apply the latest fix, which resolves some crashes problems, on my server. After the fix is applied, how do I update my existing Mobilefirst 8.0 Proguard application?
When a new fix applied to server environment, the existing application should be updated following the steps below.
1.Update proguard-project-mfp.txt (ProGuard Rules) file with the property below.
-keepclassmembers class * implements
javax.net.ssl.SSLSocketFactory {
private javax.net.ssl.SSLSocketFactory delegate;
}
2.Enable Proguard in the build.gradle file of the app module.
To
enable Proguard include the following within the android {} tag of the build.gradle file
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
}
}
Further information: https://mobilefirstplatform.ibmcloud.com/blog/2016/09/19/mfp-80-obfuscating-android-code-with-proguard/

Why am I getting a ClassNotFoundException from Play Services lib when using Proguard?

I just turned on ProGuard on my build and now I'm getting a
java.lang.ClassNotFoundException: Didn't find class "com.google.android.gms.chimera.GmsModuleInitializer" on path: DexPathList[[zip file "/system/app/PlayGames.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
The docs say that everything that I need to use Proguard with Play Services should be included by the Android Gradle plugin:
Note: ProGuard directives are included in the Play services client
libraries to preserve the required classes. The Android Plugin for
Gradle automatically appends ProGuard configuration files in an AAR
(Android ARchive) package and appends that package to your ProGuard
configuration. During project creation, Android Studio automatically
creates the ProGuard configuration files and build.gradle properties
for ProGuard use. To use ProGuard with Android Studio, you must enable
the ProGuard setting in your build.gradle buildTypes. For more
information, see the ProGuard guide.
This the important part of my app module build.gradle file:
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
...
}
...
buildTypes {
...{
applicationIdSuffix ".debug"
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
}
dependencies {
...
//google play services
compile 'com.google.android.gms:play-services-gcm:8.4.0'
compile 'com.google.android.gms:play-services-analytics:8.4.0'
compile 'com.google.android.gms:play-services-location:8.4.0'
}
This is my top level build.gradle file:
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.2'
}
}
allprojects {
repositories {
jcenter()
mavenCentral()
}
}
What am I missing?
ClassNotFoundException usually occurs when an application tries to load in a class through its string name but no definition for the class with the specified name could be found.
From this forum, you can fix it by adding com.google.android.gms.** { *; }.
Just add to your proguard-project.txt:
keep class com.google.android.gms.** { *; }
dontwarn com.google.android.gms.**
You can also check on the suggested comment in this SO question.
Google Play Services aars contain proguard.txt with the necessary clauses. So the setting shouldn't really be necessary. You can investigate what happened with the fragment in ProGuard output files. Check app/build/output/mapping/{buildVariant}/usage.txt and mapping.txt. The fragment should be mentioned in one of those.
Hope this helps!
I know this is a rather old post but I would like to highlight the following should it help someone in the future.
Like #abielita mentioned, the ClassNotFoundException is caused by an unhandled case of reflection.
When using broad -keep options (ending with .** { *; }), you will instruct ProGuard not to shrink, optimize or obfuscate all classes and classmembers for the package name mentioned before the wildcards. This will eventually lead in a poorly optimized project. Therefore, it's better to narrow down such -keep option to only target the missing class. In OP's example, adding a -keep option for the missing class like shown below will tackle this particular issue;
-keep class com.google.android.gms.chimera.GmsModuleInitializer
ProGuard can help you set up narrowed down -keep options if you add -addconfigurationdebugging to the configuration file, more details on this feature is documented in the ProGuard manual, here.
Recently the ProGuard Playground was released, you can quickly visualise the effect of the broad -keep options vs the narrowed down ones. A nice benefit here is that you do not need to continuously (re-)build the project.