You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Track the currently known feature-parity gaps and high-risk untested behavior in the trimmable typemap implementation.
The goal is not to restore every legacy implementation detail. It is to identify behavior that applications and bindings reasonably depend on, decide the intended contract, and add explicit support or an actionable diagnostic.
This list is an investigation backlog. Items without an existing focused issue are not necessarily confirmed product defects.
Known regression that prompted this audit
Forward managed attributes to Java annotations. (#12549)
Add an end-to-end NativeAOT WebView regression test in addition to generator unit tests.
The annotation regression showed that scanner and runtime coverage can remain green while the semantic contents of generated Java have changed.
Constructor and activation parity
Constructor discovery and ordinary Java-created activation now have substantial coverage, including primitives, strings, arrays, Context, IAttributeSet, exceptions, managed-first construction, and Java-first construction. The remaining risk is concentrated in less common activation paths:
Peer identity and replaceability during activation. (#12566)
Reentrant and synchronized concurrent constructor-time lookups preserve one final managed peer and exactly-once construction.
The unchanged fixture passes with llvm-ir, trimmable CoreCLR, and NativeAOT; no production fix was required.
Virtual callbacks from Java constructors. (#12566)
Added a replacement fixture using normal [Register] plus generated static/UCO registration, without unsupported dynamic native registration.
Peer identity, exactly-once construction, callback dispatch, concurrency, and exception propagation pass unchanged in all three configurations; no production fix was required.
Non-static Java inner classes — investigated; not an llvm-ir parity feature.
The llvm-ir path omits the nested derived JCW and Java activation fails with ClassNotFoundException, even with an explicit nested [Register].
A trimmable-only implementation was prototyped, but it will not be landed under the requirement that parity fixtures pass with llvm-ir first.
Confirmed trimmable typemap defect: [Export(Throws = ...)] metadata was parsed but dropped from generated Java constructors.
The unchanged constructor fixture passed with llvm-ir and failed with trimmable CoreCLR and NativeAOT before the fix; all three configurations pass after the fix.
Interface and abstract-type invoker activation. (#12565)
Confirmed trimmable typemap defect: JniTypeSignatureAttribute.InvokerType was ignored, allowing hierarchy fallback to select the wrong proxy.
Constructor-based XA, Java.Interop, inherited-interface, abstract-type, and repeated-lookup identity tests now pass with llvm-ir, trimmable CoreCLR, and NativeAOT.
Cross-assembly invokers are excluded: llvm-ir resolves invokers from the target assembly and does not support that shape.
Wrapping an existing Java object as a caller-supplied closed managed generic type was already supported; coverage now proves exactly-once activation and stable identity across all configurations.
Java-created open generic peers remain unsupported because Java cannot provide managed type arguments.
Ambiguous or unrepresentable constructor signatures. (#12567)
Added localized XA4259-XA4262 diagnostics for collapsed JNI signatures, unsupported parameter shapes, missing compatible Java base constructors, and invalid SuperArgumentsString expressions.
Validation stops before writing partial Java output and covers inferred, [Export], [Register], and [JniConstructorSignature] constructor forms.
Confirmed trimmable typemap defect: cross-assembly peers with the same generated JCW name silently overwrote one .java file while retaining duplicate/inconsistent ACW and typemap mappings.
The unchanged fixture fails with XA4215 under llvm-ir; trimmable now rejects the collision deterministically before writing typemap, Java, or ACW-map outputs.
Generated Java semantic parity.
Compare legacy XAJavaInterop1 and trimmable output for hierarchy, interfaces, constructors, methods, fields, visibility, annotations, and throws.
Normalize only intentional package-name and native-registration differences.
Compile the resulting source with javac; fragment/string assertions are insufficient.
Redundant and colliding interface declarations.
Verify most-derived interface filtering and Java-name deduplication.
Cover generic parent interfaces, covariant returns, Java bridge methods, and two managed members mapping to the same Java signature.
Unicode Java identifiers.
Determine whether valid non-ASCII Java identifiers are part of the supported contract.
If supported, ensure source paths, manifest names, DEX names, and JNI lookup use the same normalization.
[ExportField] validation and runtime coverage.
Restore validation for parameter count, void returns, duplicate/invalid names, and static versus instance initialization.
Unknown types must not silently degrade to java.lang.Object.
Require correct support or an early coded diagnostic for generic, byref, pointer, function-pointer, rectangular-array, and arbitrary managed-object signatures.
Runtime behavior
Java aliases and casts in realistic AppCompat/view inflation paths.
NativeAOT AppCompat/Forms scenarios currently contain skips for invalid casts during startup.
Add focused JavaCast<T>/JavaAs<T> coverage for aliases, interfaces, generic wrappers, and most-derived binding types.
Static/default interface methods and desugaring.
A NativeAOT device scenario is currently skipped after NoSuchMethodError.
Cover API-native and D8/R8-desugared forms, nested interfaces, and Java bridge methods.
Multi-RID and reference/implementation assembly selection.
Verify RID-specific assets and trim closures instead of relying on the first RID.
Ensure implementation assemblies are selected deterministically when reference and implementation assemblies share a simple name.
R8 incremental invalidation.
A managed reachability/DGML-only change must update keep rules and force DEX regeneration.
Fast deployment and packaging variants.
Exercise add/remove/rename of Java peers under the trimmable typemap.
Cover APK/AAB, assembly stores, ReadyToRun, single/multiple RIDs, and R8 on/off.
Explicit non-goals and intentional incompatibilities
The following should not be treated as missing parity unless the product contract changes:
Dynamic native registration and [JniAddNativeMethodRegistration] are unsupported by design. The build should reject them consistently with a coded diagnostic.
Java.Interop callable attributes such as [JavaCallable] and [JavaCallableConstructor] are currently unsupported by design. Supporting them would mean translating them into the existing generated export/constructor/UCO model, not restoring ManagedPeer; investigate only if Java.Interop-authored assemblies are supported Android inputs.
Legacy package naming policies and exact crc64... names are intentionally incompatible. Explicit [Register] names are the compatibility mechanism for externally referenced Java names.
Reflection-oriented type/value-manager APIs, including runtime ActivatePeer() and general value-marshaler lookup, are intentionally unavailable. Required product behavior should use generated proxies and marshalers.
Java-created open generic peers are unsupported because Java cannot identify the managed generic arguments.
Proposed validation strategy
Add a shared fixture corpus that can be processed by both the legacy XAJavaInterop1/llvm-ir and trimmable pipelines.
Compare parsed Java semantics, not raw source text.
Compile all generated JCWs with javac.
Run Java-created, managed-created, reentrant, and concurrent activation cases on device.
Compare Release artifacts and runtime behavior with R8 enabled and disabled.
Exercise CoreCLR Debug/Release and NativeAOT Release across multiple ABIs/RIDs.
Require explicit diagnostics for every intentional non-goal instead of allowing late runtime failures.
Summary
Track the currently known feature-parity gaps and high-risk untested behavior in the trimmable typemap implementation.
The goal is not to restore every legacy implementation detail. It is to identify behavior that applications and bindings reasonably depend on, decide the intended contract, and add explicit support or an actionable diagnostic.
This list is an investigation backlog. Items without an existing focused issue are not necessarily confirmed product defects.
Known regression that prompted this audit
@android.webkit.JavascriptInterface.The annotation regression showed that scanner and runtime coverage can remain green while the semantic contents of generated Java have changed.
Constructor and activation parity
Constructor discovery and ordinary Java-created activation now have substantial coverage, including primitives, strings, arrays,
Context,IAttributeSet, exceptions, managed-first construction, and Java-first construction. The remaining risk is concentrated in less common activation paths:Peer identity and replaceability during activation. (#12566)
Virtual callbacks from Java constructors. (#12566)
[Register]plus generated static/UCO registration, without unsupported dynamic native registration.Non-static Java inner classes — investigated; not an llvm-ir parity feature.
ClassNotFoundException, even with an explicit nested[Register].Constructor
throwsdeclarations. (#12564)[Export(Throws = ...)]metadata was parsed but dropped from generated Java constructors.Interface and abstract-type invoker activation. (#12565)
JniTypeSignatureAttribute.InvokerTypewas ignored, allowing hierarchy fallback to select the wrong proxy.Closed generic wrapper activation. (#12564)
Ambiguous or unrepresentable constructor signatures. (#12567)
SuperArgumentsStringexpressions.[Export],[Register], and[JniConstructorSignature]constructor forms.JCW and Java-source parity
Duplicate Java wrapper names. (#12569)
.javafile while retaining duplicate/inconsistent ACW and typemap mappings.Generated Java semantic parity.
throws.javac; fragment/string assertions are insufficient.Redundant and colliding interface declarations.
Unicode Java identifiers.
[ExportField]validation and runtime coverage.Unsupported export signatures.
java.lang.Object.Runtime behavior
Java aliases and casts in realistic AppCompat/view inflation paths.
JavaCast<T>/JavaAs<T>coverage for aliases, interfaces, generic wrappers, and most-derived binding types.Static/default interface methods and desugaring.
NoSuchMethodError.Plain managed-object proxy behavior.
Equals(),GetHashCode(), andToString()forwarding.JavaObjectArray<object>.Interface-valued Java collections.
Application-defined value types in containers.
Throwable round trips.
Build, trimming, and packaging
R8 retention for Java outside the managed reachability graph.
AndroidJavaSource, binding Java, JNI/reflection-only entry points, and multidex behavior.XML-created custom views and resource-designer dependencies.
AppWithStyleableUsageRunsfailure reaches the managed constructor but cannot load_Microsoft.Android.Resource.Designer.Incremental typemap correctness.
Pre-generated framework typemaps.
Multi-RID and reference/implementation assembly selection.
R8 incremental invalidation.
Fast deployment and packaging variants.
Explicit non-goals and intentional incompatibilities
The following should not be treated as missing parity unless the product contract changes:
[JniAddNativeMethodRegistration]are unsupported by design. The build should reject them consistently with a coded diagnostic.[JavaCallable]and[JavaCallableConstructor]are currently unsupported by design. Supporting them would mean translating them into the existing generated export/constructor/UCO model, not restoringManagedPeer; investigate only if Java.Interop-authored assemblies are supported Android inputs.crc64...names are intentionally incompatible. Explicit[Register]names are the compatibility mechanism for externally referenced Java names.ActivatePeer()and general value-marshaler lookup, are intentionally unavailable. Required product behavior should use generated proxies and marshalers.Proposed validation strategy
javac.