Skip to content

[r8] Obfuscate private Java members by default - #12668

Open
jonathanpeppers wants to merge 3 commits into
dotnet:mainfrom
jonathanpeppers:jonathanpeppers-selective-r8-obfuscation
Open

[r8] Obfuscate private Java members by default#12668
jonathanpeppers wants to merge 3 commits into
dotnet:mainfrom
jonathanpeppers:jonathanpeppers-selective-r8-obfuscation

Conversation

@jonathanpeppers

Copy link
Copy Markdown
Member

Description

R8 currently disables all obfuscation by default. That avoids breaking JNI names, but also prevents R8 from shortening implementation details that are safe to rename.

Preserve Java class names and public/protected member names while allowing private and package-private members to be obfuscated:

-keep,allowshrinking,allowoptimization class **
-keepclassmembers,allowshrinking,allowoptimization class ** {
   public protected *;
}

This avoids managed IL rewriting while keeping Java names that can participate in JNI stable. The NativeAOT configuration also preserves the package-private java.lang.Class fields on mono.android.Runtime because native hosts resolve those fields by literal name during startup.

Escape hatch

$(_AndroidR8DontObfuscate) is a private escape hatch only. Setting it to true restores the previous global -dontobfuscate behavior. It is not a new supported public build property or an alternative configuration mode, and it remains blank by default.

Tests

Added R8ObfuscationTests device coverage for CoreCLR and NativeAOT using an AndroidJavaSource probe. It verifies that class/public/protected names remain stable, private/package-private methods are renamed in the mapping and DEX output, and the resulting app launches and executes the JNI call successfully.

Preserve Java class names and public/protected member names while allowing R8 to obfuscate private and package-private members. Keep _AndroidR8DontObfuscate as a private escape hatch that only restores the previous global -dontobfuscate behavior.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: cf67f43d-2eef-46ac-9d52-e9a677671fc8

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.

🟡 Changes recommended

The new device test can leave apps installed on failure paths, which risks flakiness and cross-test interference in device CI runs.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR changes the default R8 behavior to allow obfuscation of private/package-private Java implementation details while keeping Java class names and public/protected member names stable for JNI compatibility, with a private MSBuild escape hatch to restore the previous global -dontobfuscate behavior.

Changes:

  • Add a new selective-obfuscation default by generating base ProGuard/R8 rules at build time (and wiring an internal $(_AndroidR8DontObfuscate) toggle).
  • Update embedded ProGuard config resources to no longer globally disable obfuscation, and add a NativeAOT-specific keep rule for mono.android.Runtime startup fields.
  • Add device integration tests validating mapping + DEX output + runtime execution for CoreCLR and NativeAOT.
File summaries
File Description
tests/MSBuildDeviceIntegration/Tests/R8ObfuscationTests.cs Adds device test coverage verifying selective obfuscation via mapping/DEX inspection and a runtime probe.
src/Xamarin.Android.Build.Tasks/Xamarin.Android.D8.targets Plumbs a private MSBuild escape hatch property into the R8 task invocation.
src/Xamarin.Android.Build.Tasks/Tasks/R8.cs Implements default selective-obfuscation ProGuard directives generation and supports DontObfuscate.
src/Xamarin.Android.Build.Tasks/Resources/proguard_xamarin.cfg Removes the global -dontobfuscate default from the common R8 config resource.
src/Xamarin.Android.Build.Tasks/Resources/proguard_trimmable_nativeaot.cfg Removes -dontobfuscate and adds a keep rule for mono.android.Runtime fields needed at NativeAOT startup.
Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread tests/MSBuildDeviceIntegration/Tests/R8ObfuscationTests.cs Outdated
Track successful installation and attempt uninstall from a finally block so assertion failures do not leave packages on the test device.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: cf67f43d-2eef-46ac-9d52-e9a677671fc8
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: cf67f43d-2eef-46ac-9d52-e9a677671fc8
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