Skip to content

[TrimmableTypeMap] Add GetStaticMethodFallbackTypesCore override for desugared default interface methods#11050

Open
Copilot wants to merge 3 commits intomainfrom
copilot/add-getstaticmethodfallbacktypescore-override
Open

[TrimmableTypeMap] Add GetStaticMethodFallbackTypesCore override for desugared default interface methods#11050
Copilot wants to merge 3 commits intomainfrom
copilot/add-getstaticmethodfallbacktypescore-override

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 30, 2026

Adds GetStaticMethodFallbackTypesCore override to TrimmableTypeMapTypeManager to support Java 8+ default interface methods desugared by D8/R8.

Problem

TrimmableTypeMapTypeManager did not override GetStaticMethodFallbackTypesCore(). Without this, calls to desugared default interface methods fail with NoSuchMethodError at runtime when using the trimmable type map. This affects any app using Java libraries with default interface methods (Java 8+ feature, very common in modern Android libraries like AndroidX).

Fix

Added the same override that already exists in ManagedTypeManager to TrimmableTypeMapTypeManager:

protected override IReadOnlyList<string>? GetStaticMethodFallbackTypesCore(string jniSimpleReference)
{
    int slash = jniSimpleReference.LastIndexOf('/');
    var desugarType = slash > 0
        ? $"{jniSimpleReference.Substring(0, slash + 1)}Desugar{jniSimpleReference.Substring(slash + 1)}"
        : $"Desugar{jniSimpleReference}";
    return new[] {
        $"{desugarType}$_CC",
        $"{jniSimpleReference}$-CC",
    };
}

This generates two fallback type names for desugared companion classes (Desugar{Type}$_CC and {Type}$-CC) so that JNI static method lookups on desugared default interface methods succeed at runtime.

Tests

Added TrimmableTypeMapTypeManagerTests to tests/Mono.Android-Tests/Mono.Android-Tests/Java.Interop/ to verify the fallback type generation. The tests use a subclass of TrimmableTypeMapTypeManager (accessible via the existing InternalsVisibleTo in Mono.Android) and cover three cases:

  • Type with a single-level package name (e.g. android/app/Activity)
  • Type without a package name (e.g. Activity)
  • Type with a deep package hierarchy (e.g. com/example/package/MyInterface)

@simonrozsival
Copy link
Copy Markdown
Member

@copilot continue

…Manager

Agent-Logs-Url: https://github.com/dotnet/android/sessions/1eb1fc88-df89-4cb7-bd45-15187eea3776

Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 31, 2026

@copilot continue

Added the GetStaticMethodFallbackTypesCore override to TrimmableTypeMapTypeManager in c0a25a0. The implementation is a direct copy from ManagedTypeManager, generating the two desugar fallback type names (Desugar...$_CC and ...$-CC) needed for D8/R8-desugared default interface methods.

Copilot AI changed the title [WIP] Add GetStaticMethodFallbackTypesCore override for TrimmableTypeMap [TrimmableTypeMap] Add GetStaticMethodFallbackTypesCore override for desugared default interface methods Mar 31, 2026
@simonrozsival simonrozsival marked this pull request as ready for review March 31, 2026 13:35
Copilot AI review requested due to automatic review settings March 31, 2026 13:35
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds support in the trimmable typemap runtime type manager for resolving Java 8+ desugared default interface method companion classes during JNI static method lookup, preventing runtime NoSuchMethodError when default interface methods are used.

Changes:

  • Added GetStaticMethodFallbackTypesCore() override to TrimmableTypeMapTypeManager.
  • Implemented desugar companion-class fallback name generation (Desugar{Type}$_CC and {Type}$-CC) consistent with ManagedTypeManager.

@simonrozsival simonrozsival added copilot `copilot-cli` or other AIs were used to author this trimmable-type-map labels Mar 31, 2026
Comment on lines +63 to +73
protected override IReadOnlyList<string>? GetStaticMethodFallbackTypesCore (string jniSimpleReference)
{
int slash = jniSimpleReference.LastIndexOf ('/');
var desugarType = slash > 0
? $"{jniSimpleReference.Substring (0, slash + 1)}Desugar{jniSimpleReference.Substring (slash + 1)}"
: $"Desugar{jniSimpleReference}";
return new[] {
$"{desugarType}$_CC",
$"{jniSimpleReference}$-CC",
};
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@copilot we are missing a new test to verify this code path works.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added tests in b8d9cca. The new TrimmableTypeMapTypeManagerTests class in tests/Mono.Android-Tests/Mono.Android-Tests/Java.Interop/TrimmableTypeMapTypeManagerTests.cs creates a subclass of TrimmableTypeMapTypeManager (accessible via the existing InternalsVisibleTo in Mono.Android) and verifies the fallback type generation for three cases: type with a package name, type without a package name, and type with a deep package hierarchy.

…Core

Agent-Logs-Url: https://github.com/dotnet/android/sessions/66cf81ea-433f-43ac-8c85-45bb0483a230

Co-authored-by: jonathanpeppers <840039+jonathanpeppers@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

copilot `copilot-cli` or other AIs were used to author this trimmable-type-map

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[TrimmableTypeMap] Add GetStaticMethodFallbackTypesCore override for desugared default interface methods

4 participants