Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

[Java.Interop] Converge Android interop implementations and eliminate duplicate runtime paths

Aperta
#12,995 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
5/5
Tempo stimato
Più di una settimana
Idoneità per principianti
15/100
Tipo di issue
Refactoring
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
csharp, java
Ambito
mobile-dev

Direzione di ricerca

Start by reading the two proxy implementations named in the issue: src/Mono.Android/Android.Runtime/JavaProxyThrowable.cs (with AndroidRuntime.cs) and external/Java.Interop/src/Java.Interop/Java.Interop/JavaProxyThrowable.cs plus JniEnvironment.Errors.cs, then src/Microsoft.Android.Runtime.NativeAOT/Java.Interop/JreRuntime.cs and UncaughtExceptionMarshaler.cs. Run the focused BuildProguardEnabledProject test in src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs under both CoreCLR and NativeAOT to see the current runtime-specific assertions. Done means both runtimes dispatch through android.runtime.JavaProxyThrowable with the listed round-trip, stack-trace and peer-lifetime tests passing, and the unused proxy/JAR/typemap plumbing removed. This is multi-phase architectural work; the first task is producing the inventory and split into focused PRs, not making an edit.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

needs-triage
Android framework version

net11.0-android (Preview)

Affected platform version

Current dotnet/android development sources; CoreCLR and NativeAOT. This is an architectural cleanup proposal, not an OS-specific failure.

Description

Move Java.Interop and Mono.Android toward a single coherent Android interop implementation, eliminating historical "two ways of doing things" where the split is no longer necessary.

Direction: Android's supported runtime requirements should drive this work. Preserving Java.Interop independently of Android is not, by itself, a reason to retain duplicate implementations. Preserve required semantics and public contracts, rather than maintaining parallel internal mechanisms solely because of their historical ownership.

This should be incremental follow-up work, separate from PR #12890. Aligning behavior need not wait for an assembly merge; evaluate assembly/dependency consolidation separately if it meaningfully simplifies the architecture.

First concrete target: exception proxies

CoreCLR dispatch uses Android.Runtime.JavaProxyThrowable, backed by android.runtime.JavaProxyThrowable. NativeAOT creates JreRuntime and inherits Java.Interop's exception dispatch, which uses Java.Interop.JavaProxyThrowable, backed by net.dot.jni.internal.JavaProxyThrowable.

These paths differ in more than the Java name: creation, managed-exception unwrapping, stack-trace translation, and uncaught-exception reporting need to agree. Java.Lang.Throwable.FromException() already creates the Android platform proxy.

Removing the legacy platform JAR in #12890 exposed this split in an R8 packaging test. The immediate test fix correctly checks each runtime's current proxy, but does not resolve the architectural duplication. Both runtime/RID variants pass with that fix, and Java-to-managed-to-Java exception propagation was verified locally for both runtimes.

  • Converge CoreCLR and NativeAOT on one Android exception-proxy implementation, preferably the existing android.runtime.JavaProxyThrowable.
  • Unify creation and unwrapping across runtime dispatch, direct Java.Interop exception-throwing APIs, and NativeAOT uncaught-exception reporting. Do not change only the Java class name or one runtime override.
  • Retain original managed exceptions and their identity where supported, preserve Java exceptions, and define consistent message/stack-trace behavior.
  • Ensure real NativeAOT reachability retains the generated platform peer and its required constructors under ILC and R8; do not restore the legacy platform JAR.
  • Once all consumers are migrated, remove the redundant proxy implementation and associated generated-Java, JAR, typemap, native JNI lookup, and keep-rule plumbing that is genuinely unused.

Broader convergence audit

Inventory remaining parallel mechanisms for proxy creation/unboxing, peer lifetime and GC bookkeeping, activation/type resolution, Java generation, and runtime packaging. For each, identify whether the difference is required by CoreCLR/NativeAOT or merely historical, then split actionable consolidation work into focused PRs.

Do not assume apparently similar implementations are interchangeable: for example, managed-object proxy equality/hash-code/string-conversion semantics need an explicit decision before consolidation.

Related: #11727 — Remove support for experimental JavaInterop1 codegen. Coordinate with that work and revisit its standalone-preservation assumptions rather than creating contradictory cleanup plans.

Acceptance criteria for the exception-proxy phase

Both runtimes use the same Android proxy for managed exception dispatch. Tests cover original-exception round-trips, exported methods and throwing constructors, nested callbacks, uncaught-exception reporting/events, stack traces, pending-exception cleanup, and peer/reference lifetime. Release builds with and without R8 retain the required peer/constructors; obsolete proxy artifacts are absent after their consumers have been removed. Runtime-specific assertions remain only where there is a documented, necessary behavioral difference.

Steps to Reproduce

This is a convergence proposal rather than a new failure report. The current split can be inspected in:

  • src/Mono.Android/Android.Runtime/AndroidRuntime.cs and JavaProxyThrowable.cs.
  • src/Mono.Android/Java.Lang/Throwable.cs.
  • src/Microsoft.Android.Runtime.NativeAOT/Java.Interop/JreRuntime.cs and UncaughtExceptionMarshaler.cs.
  • external/Java.Interop/src/Java.Interop/Java.Interop/JniRuntime.cs, JniEnvironment.Errors.cs, JavaProxyThrowable.cs, and JniRuntime.JniValueManager.cs.
  • src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs, test BuildProguardEnabledProject.
Did you find any workaround?

PR #12890's runtime-specific DEX assertions reflect the current supported behavior. They are an immediate test correction, not the proposed convergence. No legacy compatibility path needs to be restored.

Relevant log output

N/A. The investigation, focused fix, exact validation commands, and local results are recorded in this PR comment.

Lingua principale
C#
Stelle
2.1k
Fork
581
Merge medio
2g 3h
PR unite (30g)
216

Preparare l'ambiente

  • Nessun Dockerfile né file Docker Compose
  • Ha un modello di pull request
  • Nessuna guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di dotnet/android

Tutte le issue di dotnet/android

Issue simili

Altre issue su C#

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.