Search code examples
androidproguardobfuscationandroid-r8

How can I obfuscate the package names for two different `.aar` without having duplicate class collision?


Let's say I have 3 subprojects (modules):

:libraryA
:libraryB
:app

:app depends on both :libraryA and :libraryB. In my libraries, I have:

// libraryA
com.example.libraryA.Class1
// libraryB
com.example.libraryB.Class2

When I run R8 (like proguard) over these two libraries, they generate the following classes:

// libraryA - Class1
a.a.a.a
// libraryB - Class2
a.a.a.a

(note that 2 different classes end up having the same signature)

When I build a variant of :app that uses the obfuscated .aars of :libraryA and :libraryB, I get the following build failure:

Caused by: com.android.tools.r8.utils.b: Type a.a.a.a is defined multiple times:

One solution is to use -keeppackagenames in my proguard rules for the libraries

-keeppackagenames com.example.**

But I want to actually obfuscate the package name. What are my options here?

Is it possible to obfuscate package names in a unique but deterministic basis? For example, I would like the following to occur:

  • com.example.libraryA -> a.a.a
  • com.example.libraryB -> a.a.b

This would avoid any potential conflicts. Is something like this achievable?


Solution

  • When you package libraries with R8 for distribution you have to use -keeppackagenames, as otherwise consumers of the library can get duplicate classes.

    There are options -flattenpackagehierarchy and -repackageclasses to control where non-kept classes go. For the R8 library itself we use both.

    However, when you are building a final app consuming the libraries all of the app including the libraries will be obfuscated as a whole, so the libraries does not have to be obfuscated when used as dependencies.