145

I want to exclude some file paths from ProGuard. Example com.myapp.customcomponents

How can I do this? I hate to be placing -keep flags for every single custom component file I have in this directory.

I have tried the following but it doesn't work:

-keep public class com.myapp.customcomponents.*
Macarse
  • 91,829
  • 44
  • 175
  • 230
Jona
  • 13,325
  • 15
  • 86
  • 129

5 Answers5

300

You don't specify in what way it doesn't work. Your configuration keeps the names of all public classes in the specified package:

-keep public class com.myapp.customcomponents.*

The following configuration keeps the names of all public classes in the specified package and its subpackages:

-keep public class com.myapp.customcomponents.**

The following configuration keeps the names of all public/protected classes/fields/methods in the specified package and its subpackages:

-keep public class com.myapp.customcomponents.** {
  public protected *;
}
Eric Lafortune
  • 45,150
  • 8
  • 114
  • 106
86

Add the following line at the bottom of your ProGuard configuration:

-keep class com.facebook.** { *; }

Replace package name accordingly, here the package com.facebook will be excluded from ProGuard.

sam1370
  • 335
  • 2
  • 18
Pawan Maheshwari
  • 15,088
  • 1
  • 48
  • 50
13

What worked for me using Android Studio 4.0 is:

-keepclassmembers class com.myapp.customcomponents.* {
    <fields>;
    <init>();
    <methods>;
}

Double asterisks (**) in other answers did not work for me. I also tried the above configuration with R8, works fine.

mtsahakis
  • 793
  • 1
  • 8
  • 18
1

Lots of people seem to recommend -keep class com.myapp.customcomponents.** { *; } as a way to exclude a path from being processed. See here:

  1. exclude packages from proguard
  2. Make Proguard completely ignore package
  3. Prevent a directory from proguard obfuscation

The problem with this solution is that there is still some level of obfuscation happening, which can break your code. You can see the mapping in the mapping print out:

java.lang.String toString() -> toString
int getMemoizedSerializedSize() -> getMemoizedSerializedSize
void setMemoizedSerializedSize(int) -> setMemoizedSerializedSize
int getSerializedSize() -> getSerializedSize
boolean equals(java.lang.Object) -> equals
int hashCode() -> hashCode

The solution I have opted for is a two step process. First, use injars with a filter to select the package path I would like to process. It is possible to add the other package pathes as libraries.

-injars       artifacts/in.jar(org/toprocess/**.class)
-outjars      out/processed.jar
-libraryjars  artifacts/in.jar(org/skipped/**.class)
-libraryjars  artifacts/in.jar(org/moreskipped/**.class)

Second, merge the processed jar with the original jar, but only those paths that were skipped.

-injars  out/processed.jar
-injars  artifacts/in.jar(org/skipped/**.class)
-injars  artifacts/in.jar(org/moreskipped/**.class)
-outjars out/merged.jar

-dontshrink
-dontoptimize
-dontobfuscate

The result is a merged jar that is the combination of the processed package path and the skipped paths. This exercise is invalid, if someone can provide a way to skip processing of certain paths completely (which I haven't found).

PLG
  • 448
  • 5
  • 21
1

Put all your models-related include models, requests and responses object into a central sub package.

For example: com.example.models

Then add this line to your proguard-rules.pro file:

-keepclassmembers class com.example.models.** { <fields>; }
Tran Chien
  • 614
  • 4
  • 10