I want to enable ProGuard in library module but getting compilation error that package does not exists. Why package not exists after apply ProGuard in library module?
library module build.gradle
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
Log Error
/home/hitesh/Documents/Android Studio Project/ALPR-Sample/app/src/main/java/com/alpr/sample/GalleryActivity.java
Error:(15, 32) error: package com.alprlib.alpr.doc does not exist
Error:Execution failed for task ':app:compileDebugJavaWithJavac'.
> Compilation failed; see the compiler error output for details.
here doc class file exist in library module
ProGuard file rules
-keep class com.alprlib.alpr.** { *; }
-keepclassmembers class alprlib.alpr.** {*;}
It makes sense to me to specify proguard settings for a library (like which library files shouldn't be obfuscated) in the library project. I've found that I also need to include proguard configurations from my library modules in my application. To do this, I added the following to the defaultConfig section in my library's build.gradle
consumerProguardFiles 'proguard-rules.pro'
and then configured the proguard-rules.pro file in my library module to keep the names of important serialized classes.
See also consumerProguardFiles
Please see this post:
https://stackoverflow.com/a/48636288/8770663
you can write on your proguard file -
-keep public class * extends android.app.Activity
Or what ever class you want to keep.
Have a look on this - https://www.guardsquare.com/en/proguard/manual/examples
Related
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.**,**
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'
My project compiles and executes well on debug mode but when i try to generate a signed apk, errors arise. This appears on the message log:
:app:proguardRelease
Warning:android.support.v4.app.DialogFragment: can't find referenced class android.support.v4.app.DialogFragment$DialogStyle
Warning:android.support.v4.app.FragmentTransaction: can't find referenced class android.support.v4.app.FragmentTransaction$Transit
Warning:android.support.v4.view.ViewCompat: can't find referenced class android.support.v4.view.ViewCompat$ResolvedLayoutDirectionMode
Warning:android.support.v4.view.ViewCompat: can't find referenced class android.support.v4.view.ViewCompat$LayoutDirectionMode
Warning:android.support.v4.view.ViewCompat: can't find referenced class android.support.v4.view.ViewCompat$LayerType
Warning:android.support.v4.view.ViewCompat: can't find referenced class android.support.v4.view.ViewCompat$AccessibilityLiveRegion
Warning:android.support.v4.view.ViewCompat: can't find referenced class android.support.v4.view.ViewCompat$ImportantForAccessibility
Warning:android.support.v4.view.ViewCompat: can't find referenced class android.support.v4.view.ViewCompat$OverScroll
Warning:android.support.v4.widget.DrawerLayout: can't find referenced class android.support.v4.widget.DrawerLayout$EdgeGravity
Warning:android.support.v4.widget.DrawerLayout: can't find referenced class android.support.v4.widget.DrawerLayout$LockMode
Warning:android.support.v4.widget.DrawerLayout: can't find referenced class android.support.v4.widget.DrawerLayout$State
Warning:there were 11 unresolved references to classes or interfaces.
You may need to add missing library jars or update their versions.
If your code works fine without the missing classes, you can suppress
the warnings with '-dontwarn' options.
(http://proguard.sourceforge.net/manual/troubleshooting.html#unresolvedclass)
Exception while processing task
java.io.IOException: Please correct the above warnings first.
at proguard.Initializer.execute(Initializer.java:473)
at proguard.ProGuard.initialize(ProGuard.java:233)
at proguard.ProGuard.execute(ProGuard.java:98)
at proguard.gradle.ProGuardTask.proguard(ProGuardTask.java:1074)
at com.android.build.gradle.tasks.AndroidProGuardTask.doMinification(AndroidProGuardTask.java:139)
at com.android.build.gradle.tasks.AndroidProGuardTask$1.run(AndroidProGuardTask.java:115)
at com.android.builder.tasks.Job.runTask(Job.java:48)
at com.android.build.gradle.tasks.SimpleWorkQueue$EmptyThreadContext.runTask(SimpleWorkQueue.java:41)
at com.android.builder.tasks.WorkQueue.run(WorkQueue.java:227)
at java.lang.Thread.run(Thread.java:745)
:app:dexRelease UP-TO-DATE
:app:crashlyticsStoreDeobsRelease
:app:crashlyticsUploadDeobsRelease
:app:validateExternalOverrideSigning
:app:packageRelease FAILED
Error:Execution failed for task ':app:packageRelease'.
> Unable to compute hash of /home/kombo/RAL/Mpasho/app/build/intermediates/classes-proguard/release/classes.jar
I have tried every possible way of remedying this by updating my build tools, using the latest gradle version, checking all the dependencies and the error still shows up.
I am pretty sure the v4 support library is present in the project since no errors arise in debug mode.
I also had this issue when upgrading everything that is built related to 23 (Android Libraries, SDK etc).
This proguard configuration fixed it for me:
-dontwarn org.apache.http.**
-dontwarn android.net.http.AndroidHttpClient
-dontwarn com.google.android.gms.**
-dontwarn com.android.volley.toolbox.**
Source
Turns out I had omitted the getDefaultProguardFile('proguard-android.txt') line on the proguard files and was just using proguard-rules.pro
added these two line in progaurd
-dontwarn android.net.http.AndroidHttpClient
-dontwarn com.google.android.gms.**
and it works..
It is related to library used in project.
The default ProGuard file already has a rule to ignore support library warnings. If you don't have it you can add to your file
-dontwarn android.support.**
but would be better to add the default one. See Proguard configuration#Android Developers
This also could happen due to errors/warnings related to included .jar files
Check in build output for proguard warnings/errors.
I had issue related to opencsv jar file. Hint by Lakedaemon in above comment helped me and its solved.
Try to look up in the whole error message. It may contain info that you include a library twice. This was the problem in my case and it was fixed after removing duplicated includes.
Try add this code in your proguard-rules.pro:
-ignorewarnings
It solved my problem.
I think your app build.gradle buildTypes > release > minifyEnabled is true
That cause you get this error message.
Avoid this error message, set buildTypes > release > minifyEnabled is false
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
I have created the .aar file (containing the resources & drawables) of an Android library project using
./gradlew assemble
I have enabled obfuscating by setting minify == true
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
However when I run the mentioned gradle command with minify enabled = true, I get java.io.IOException: The output jar is empty. Did you specify the proper '-keep' options?
What does this error pointing to and how can I obfuscate the library .aar file?
Best Regards
Using Proguard worked like a charm for me!
Proguard is used to shrink, obfuscate, optimize code. Proguard is
necessary for your library to remove unused code and make reverse
engineering little difficult. Proguard rules for the library are
different from the normal applications. As you know, Proguard renames
classes, variables, and methods using meaningless names. You would
like to keep the names of those methods and classes as it is that
developers will call. You will need to test and verify obfuscated code
from generated AAR file.
Library Module
build.gradle of your library
buildTypes {
release {
// Enables code shrinking, obfuscation, and optimization for only
// your project's release build type.
minifyEnabled true
// Includes the default ProGuard rules files that are packaged with
// the Android Gradle plugin. To learn more, go to the section about
// R8 configuration files.
proguardFiles getDefaultProguardFile(
'proguard-android-optimize.txt'),
'proguard-rules.pro'
}
}
Inside of your proguard-rules.pro of your library
# Save the obfuscation mapping to a file, so we can de-obfuscate any stack
# traces later on. Keep a fixed source file attribute and all line number
# tables to get line numbers in the stack traces.
# You can comment this out if you're not interested in stack traces.
-printmapping out.map
-keepparameternames
-renamesourcefileattribute SourceFile
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,EnclosingMethod
# Preserve all annotations.
-keepattributes *Annotation*
# Preserve all public classes, and their public and protected fields and
# methods.
-keep public class * {
public protected *;
}
# Preserve all .class method names.
-keepclassmembernames class * {
java.lang.Class class$(java.lang.String);
java.lang.Class class$(java.lang.String, boolean);
}
# Preserve all native method names and the names of their classes.
-keepclasseswithmembernames class * {
native <methods>;
}
# Preserve the special static methods that are required in all enumeration
# classes.
-keepclassmembers class * extends java.lang.Enum {
public static **[] values();
public static ** valueOf(java.lang.String);
}
# Explicitly preserve all serialization members. The Serializable interface
# is only a marker interface, so it wouldn't save them.
# You can comment this out if your library doesn't use serialization.
# If your code contains serializable classes that have to be backward
# compatible, please refer to the manual.
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
static final java.io.ObjectStreamField[] serialPersistentFields;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
# The library may contain more items that need to be preserved;
# typically classes that are dynamically created using Class.forName:
# -keep public class mypackage.MyClass
# -keep public interface mypackage.MyInterface
# -keep public class * implements mypackage.MyInterface
Thanks to .... reference
https://dev.to/mohitrajput987/develop--publish-your-own-sdk-in-android---part-2getting-started-with-sdk-development-3159
Proguard cuts unused classes. Libraries are standalone products, and has some specific entry points, which should not be obfsuscated. So you need to add rules to keep this entry points. Rules lookes like this:
-keep class packagename {public *;}
Copy library.pro file to your library project from this location:
...\android-sdk\tools\proguard\examples
Comment these lines when building from Android Studio, it should be probably kept/updated when building from the command line:
-injars in.jar
-outjars out.jar
-libraryjars /lib/rt.jar
Update your library project build.gradle file to use library.pro:
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'library.pro'
}
Sync and build the project and it should generate an obfuscated AAR file now.
Two suggestions:
Please ensure this file exist in the library module:
proguard-rules.pro.
Please try running "./gradlew :mylib:assembleRelease" with the
"mylib" be replaced with your library module name.
Warning:library class org.apache.http.conn.ManagedClientConnection extends or implements program class org.apache.http.HttpClientConnection
despite having -dontwarn org.apache.** in my proguard rules file
Warning:org.joda.time.Weeks: can't find referenced class org.joda.convert.FromString
despite having -dontwarn org.joda.** in my proguard rules file, and -keep class org.** { *; } along with -keep interface org.** { *; }
Warning:there were 140 instances of library classes depending on program classes.
Error:Execution failed for task ':app:proguardRelease'.
> java.io.IOException: Please correct the above warnings first.
so then I look at my app structure
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-project.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
zipAlignEnabled true
}
}
proguard-project.txt is in the same folder as this build.gradle file in this module.
Not sure what is broken now, I guess there is something else that nobody told me about when I was required to update to Build Tools 21.1.1 to make other things work. any insight appreciated.
My solution was to copy all of my rules into proguard-rules.pro which the IDE had previously automatically generated for me, and then proguard worked as expected
I still don't know where getDefaultProguardFile('proguard-project.txt') is supposed to be located, but it is not being read, I moved it within my module and in the root folder of the project.