Skip to content
This repository was archived by the owner on Nov 10, 2023. It is now read-only.
This repository was archived by the owner on Nov 10, 2023. It is now read-only.

AAR that contains R.class has that class overwritten by Buck assumptions #207

@jhansche

Description

@jhansche

The scenario here is an AAR file that has no resources in its res/ directory, and has no R.txt file. The AAR has a classes.jar that includes an R.class that was created as a result of what appears to be an obfuscation pass (proguard or otherwise) -- that assumption is made based on the fact that there are several other adjacent classes with single-character names: Q.class, R.class, S.class, etc. Ordinarily, if there is no R.txt, then no resources-related R.class should be generated for it (and this works correctly in a Gradle build, for example: there is no build/generated/source/r/debug/com/crashlytics/android/R.java file, because the AAR contains no R.txt).

Buck appears to be assuming that all AAR files require an R.class, even if it has an empty res/ and missing R.txt, so it ends up generating an empty R.class for that package. However, in this case, that class ends up overwriting the R class that already exists in classes.jar. That causes an error with the caching system, reporting an error due to "Multiple entries with the same key":

Multiple entries with same key: com/crashlytics/android/R=3040495ca6cb51bd19a9878a5a73ae8093cdb0fd and com/crashlytics/android/R=2dd42ddb490ce969a59fcfd0e692f3ee1accafad

Checking the buck-out/ directory shows that the entries come from two different places:

buck-out//gen/aars__crashlytics-2.0.3#aar_prebuilt_jar.classes.txt:com/crashlytics/android/R 2dd42ddb490ce969a59fcfd0e692f3ee1accafad
buck-out//bin/__app#aapt_package_rdotjava_classes__/classes.txt:com/crashlytics/android/R 3040495ca6cb51bd19a9878a5a73ae8093cdb0fd

Presumably, the one in #aar_prebuilt_jar.classes.txt is the true R.class that exists in the classes.jar of the AAR. The one in #aapt_package_rdotjava_classes__/classes.txt appears to be the automatically generated R.class as a result of the aapt resources processing.

In an effort to get past this error just to get the project to compile, I deleted the entry from the #aapt_package_ version, and that allowed it to continue to the smart_dex step. At this point I hit a GC overhead limit exceeded error (this is caused by dx not having a large enough heap size: my project requires a 3GB heap for dex to succeed). But that's a separate issue.

After adjusting the heap size in the dx shell script, the dex tool itself then hit an error with:

java.lang.IllegalArgumentException: already added: Lcom/crashlytics/android/R;

It's already added because it is still trying to add both the real (obfuscated) R.class and the generated (R.txt) R.class.

I'm not sure if this should be reported as an issue to the Crashlytics team (since having an R.class in the library's own package scope can be seen as risky and should probably be avoided). However, since all other build tools seem to work perfectly fine with this scenario, I'm going to assume that it's a bug in buck in that it generates the resources R.class for an AAR that does not want one.

An AAR that exhibits this behavior is the Crashlytics SDK (both versions 1.2.0 and 2.0.3). The URL to download the AAR from their Maven repository: crashlytics-2.0.3.aar.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions