Skip to content

Document package relocation using R8 - #2173

Merged
Goooler merged 1 commit into
mainfrom
g/20260810/note-relocation
Aug 10, 2026
Merged

Document package relocation using R8#2173
Goooler merged 1 commit into
mainfrom
g/20260810/note-relocation

Conversation

@Goooler
Goooler force-pushed the g/20260810/note-relocation branch 2 times, most recently from 7ecb238 to 3f77569 Compare August 10, 2026 07:49
@Goooler
Goooler requested a lite review from Copilot August 10, 2026 08:02

Copilot AI 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.

Pull request overview

This PR adds user-facing documentation and functional test coverage for using R8 repackaging (-repackageclasses) as an alternative approach to package relocation, and centralizes shared functional-test helpers for R8 setup.

Changes:

  • Document “Relocating with R8”, including configuration examples and a comparison with Shadow’s built-in relocate.
  • Add functional tests covering R8 repackaging behavior and its interaction with service-file merging.
  • Refactor duplicated writeR8Repository() helper into BasePluginTest and add a bytecode helper for generating minimal .class entries.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ServiceFileTransformerTest.kt Adds a functional test for mergeServiceFiles + R8 repackaging.
src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/RelocationTest.kt Adds a functional test asserting output structure when using R8 repackaging.
src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/MinimizeTest.kt Removes duplicated writeR8Repository() helper (moved to base).
src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/CachingTest.kt Removes duplicated writeR8Repository() helper (moved to base).
src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/BasePluginTest.kt Centralizes writeR8Repository() and adds createEmptyClassBytes() for tests.
docs/configuration/relocation/README.md Adds documentation section for using R8 repackaging for relocation and compares approaches.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +170 to +191
assertThat(outputShadowedJar).useAll {
containsOnly(
"bar/",
"bar/BarDriver.class",
"com/",
"com/example/",
"com/example/Driver.class",
"foo/",
"foo/FooDriver.class",
"META-INF/services/",
"META-INF/services/com.example.Driver",
*manifestEntries,
)
getContent("META-INF/services/com.example.Driver")
.isEqualTo(
"""
|foo.FooDriver
|bar.BarDriver
|"""
.trimMargin()
)
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This has been fixed in #2174.

Copilot AI 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.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

Suppressed comments (2)

src/functionalTest/kotlin/com/github/jengelman/gradle/plugins/shadow/transformers/ServiceFileTransformerTest.kt:131

  • The test name suggests R8 relocation is being validated, but the assertions only check non-repackaged class paths and the original service descriptor names/content. Given Shadow generates -keep class ... rules for META-INF/services/** entries (which keeps names), this test is really validating that service files are still merged/kept when R8 is enabled, not that relocation happens. Renaming the test to reflect its actual expectation would avoid confusion and false assumptions about relocation behavior.
  @Test
  fun serviceResourceTransformerWithR8Relocation() {
    val one = buildJarOne {

docs/configuration/relocation/README.md:258

  • This section documents R8 repackaging, but it doesn’t mention that Shadow’s R8 integration generates -keep class ... rules for service interfaces/providers listed in META-INF/services/** (see serviceProguardRules in R8Minimizer.kt). Those keep rules preserve class names, which can prevent -repackageclasses from relocating service types unless users also adapt the service descriptor resources. Adding a short note here would set correct expectations for ServiceLoader-based dependencies.
R8 performs whole-program analysis during its minimization pass to safely relocate classes while respecting Java
access visibility constraints (such as package-private and `protected` members). Repackaging works with
`-repackageclasses` alone. Adding [-allowaccessmodification][allowaccessmodification] is optional, but allows R8 to
relocate additional classes by widening package-private or protected access restrictions to `public`. For more details
on R8 rules, see the [Global options for additional optimization][android-r8-global-options] and ProGuard manual for
[-repackageclasses][repackageclasses] and [-allowaccessmodification][allowaccessmodification].

@Goooler
Goooler force-pushed the g/20260810/note-relocation branch from a1b0855 to 9ecfe03 Compare August 10, 2026 08:26
@Goooler
Goooler force-pushed the g/20260810/note-relocation branch from 9ecfe03 to bf71eba Compare August 10, 2026 08:28
@Goooler
Goooler merged commit 41b7ebc into main Aug 10, 2026
8 checks passed
@Goooler
Goooler deleted the g/20260810/note-relocation branch August 10, 2026 08:41
Sign up for free to 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.

2 participants