Skip to content

ADFA-5073: Dedupe 7 byte-identical androidx LICENSE.txt files - #1645

Closed
davidschachterADFA wants to merge 2 commits into
stagefrom
task/ADFA-5073-dedupe-androidx-license-files
Closed

ADFA-5073: Dedupe 7 byte-identical androidx LICENSE.txt files#1645
davidschachterADFA wants to merge 2 commits into
stagefrom
task/ADFA-5073-dedupe-androidx-license-files

Conversation

@davidschachterADFA

@davidschachterADFAdavidschachterADFA commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

Found while auditing a debug APK's contents for unneeded/duplicate files (ADFA-5073).

Each androidx artifact (room-common, lifecycle-common, lifecycle-common-java8, constraintlayout-core, collection, collection-ktx, annotation) ships its own copy of the exact same Apache 2.0 LICENSE.txt (10,175 bytes each, 7 copies total). Since each copy lands at a unique per-artifact path (the artifact name is embedded in the path itself), pickFirsts can't dedupe them — there's no path collision for it to resolve. Excluded them via the same packaging.resources.excludes mechanism this file already uses for other non-functional bundled license/notice text (e.g. the log4j NOTICE exclude just above it).

Verified

  • :app:assembleV8Debug succeeds.
  • Resulting APK has zero META-INF/androidx/**/LICENSE.txt entries (down from 7, ~71KB).
  • spotlessCheck clean.

Test plan

  • Clean :app:assembleV8Debug build succeeds
  • Confirmed via unzip -l that the duplicate license files are gone
  • spotlessApply/spotlessCheck clean

🤖 Generated with Claude Code

Each androidx artifact (room-common, lifecycle-common,
lifecycle-common-java8, constraintlayout-core, collection,
collection-ktx, annotation) ships its own copy of the same Apache 2.0
LICENSE.txt at a unique per-artifact path, so pickFirsts can't dedupe
them (no path collision to resolve). Excluded via the same
packaging.resources mechanism already used for other non-functional
bundled license/notice text in this file (e.g. the log4j NOTICE
exclude just above).
Verified: the resulting debug APK has zero META-INF/androidx/**/LICENSE.txt
entries, down from 7 (~71KB).

@claudeclaudeBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.

Tip: disable this comment in your organization's Code Review settings.

@coderabbitai

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough
  • Excludes seven duplicate AndroidX LICENSE.txt files from APK packaging with packaging.resources.excludes.
  • Reduces the APK size by approximately 71 KB.
  • Verified that :app:assembleV8Debug and spotlessCheck pass.
  • Verified that the APK contains no META-INF/androidx/**/LICENSE.txt entries.
  • Risk: This change removes duplicate license copies from the APK. It must not remove the only required license notice for any dependency.

Walkthrough

The Android packaging configuration excludes duplicated AndroidX license files from the application package.

Changes

AndroidX Packaging

Layer / File(s)Summary
AndroidX license exclusion
app/build.gradle.kts
Adds a packaging exclusion for AndroidX license files under META-INF/androidx/**/LICENSE.txt.

Estimated code review effort: 1 (Trivial) | ~2 minutes

Possibly related PRs

Suggested reviewers:jomen-adfa, itsaky-adfa, hal-eisen-adfa

Poem

A rabbit checks the build with care,
While license files repeat in there.
One exclusion clears the way,
For a cleaner package at the end of day.
Hop, hop, build complete! 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly describes excluding seven duplicate AndroidX LICENSE.txt files, which is the main change.
Description check✅ PassedThe description explains the duplicate AndroidX license files, the packaging exclusion, and the verification results.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch task/ADFA-5073-dedupe-androidx-license-files

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app/build.gradle.kts`:
- Around line 154-156: Update the packaging configuration around the
META-INF/androidx/**/LICENSE.txt exclusion to retain one complete Apache-2.0
license copy in the distributed app. Add a shared app-provided license resource
through pickFirsts or APK assets, and ensure the OSS notices flow includes the
full license text and required attribution before excluding the per-artifact
AndroidX files.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8f161e9b-401d-4eb6-934c-2b1bd97ddb14

📥 Commits

Reviewing files that changed from the base of the PR and between 62d5573 and 4892cc6.

📒 Files selected for processing (1)
  • app/build.gradle.kts

Comment threadapp/build.gradle.kts Outdated
Comment on lines +154 to +156
// Each androidx artifact ships its own copy of the identical Apache 2.0 LICENSE.txt at a
// unique per-artifact path, so pickFirsts can't dedupe them (no path collision to resolve).
excludes += "META-INF/androidx/**/LICENSE.txt"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bashset -euo pipefail
echo"License and notice files:"
fd -HI -t f 'LICENSE|NOTICE'.echo"Potential OSS notices UI or resource handling:"
rg -n -i 'open.?source|third.?party|license|notice' \
--glob '*.{kt,java,xml,gradle.kts}'.echo"APK license entries, if an APK is available:"
apk="$(fd -HI -t f -e apk .| head -n 1 || true)"if [ -n"$apk" ];then
unzip -l "$apk"| rg -i '(^|/)(LICENSE|NOTICE)'fi

Repository: appdevforall/CodeOnTheGo

Length of output: 50381


🏁 Script executed:

#!/usr/bin/env bashset -euo pipefail
echo"Top-level files:"
git ls-files | awk -F/ '{print $1}'| sort -u
echoecho"App gradle packaging block context:"
sed -n '130,175p' app/build.gradle.kts 2>/dev/null ||trueechoecho"Root-level license files:"
git ls-files | awk -F/ '$2 == "" && toupper($0) ~ /^(LICENSE|NOTICE|README)(\..*)?$/ {print}'echoecho"Scoped OSS/license/notice declarations around app module:"
rg -n -i --glob '*.{kt,java,xml,gradle.kts}''open[ _-]?source|third[ _-]?party|license|notice|Apache[ _-]?2\.0' app ||trueechoecho"Scoped packaged META-INF license/notice files in tracked jars/apks:"
git ls-files | grep -E '\.(aar|jar|apk)$'|whileread -r f;doifcommand -v jar >/dev/null;thenecho"--- $f"
jar tf "$f"2>/dev/null | grep -E '^[^/]*\.txt/|^META-INF/([^/]+/)*(LICENSE|NOTICE)\.txt$'||truefidoneechoecho"Android resource-only license-related files:"
git ls-files | grep -E 'res/(.*license.*|.*oss.*|.*notice.*)|assets/(.*license.*|.*oss.*|.*notice.*)'||true

Repository: appdevforall/CodeOnTheGo

Length of output: 50381


Keep one complete Apache-2.0 license copy in the distributed app.

META-INF/androidx/**/LICENSE.txt removes AndroidX license files from the APK. Add a shared app-provided license resource in pickFirsts or the APK assets if the OSS notices flow does not already include the full Apache-2.0 license text and attribution requirements.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@app/build.gradle.kts` around lines 154 - 156, Update the packaging
configuration around the META-INF/androidx/**/LICENSE.txt exclusion to retain
one complete Apache-2.0 license copy in the distributed app. Add a shared
app-provided license resource through pickFirsts or APK assets, and ensure the
OSS notices flow includes the full license text and required attribution before
excluding the per-artifact AndroidX files.

Code review caught a real gap in the original fix: these 7 files are
not build-metadata cruft like the other entries in this exclude list
(log4j NOTICE, .proto sources, version.properties) -- Google embeds
META-INF/androidx/<group>/<artifact>/LICENSE.txt directly inside the
androidx artifacts themselves (confirmed in lifecycle-common-java8's
own jar), deliberately, per artifact.
There's no clean way to keep "just one" copy that's both correct and
resilient to dependency churn: pickFirsts can't merge these (each sits
at a distinct path, so there's no collision for it to resolve -- the
same reason it didn't work the first time this was tried), hardcoding
which single artifact's copy survives is fragile against version
bumps, and standing up an app-owned OSS-notices asset/screen to
replace them is out of scope for what was meant to be a one-line
packaging tweak. With no compensating in-app notices flow elsewhere,
stripping all 7 isn't worth the ~71KB saved in a 200MB+ APK.
Verified: :app:assembleV8Debug succeeds and all 7 license files are
present again in the built APK.
@davidschachterADFA

Copy link
Copy Markdown
CollaboratorAuthor

Closing: code review caught that these 7 LICENSE.txt files aren't build-metadata cruft like the other entries in that exclude list — Google deliberately embeds META-INF/androidx///LICENSE.txt inside the androidx artifacts themselves (confirmed directly in lifecycle-common-java8's own jar), per artifact. There's no clean way to keep just one copy that's both correct and resilient to dependency version churn, and with no compensating OSS-notices flow elsewhere in the app, stripping all 7 for ~71KB (in a 200MB+ APK) isn't worth the risk. Reverted in 405c016; this branch now has a zero diff against stage. See ADFA-5073 for the full trail.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@davidschachterADFA