[release/10.0.1xx] [xabt] Fix wrong-TFM assembly loading -> empty .jlo.xml files#11248
Draft
jonathanpeppers wants to merge 6 commits intorelease/10.0.1xxfrom
Draft
[release/10.0.1xx] [xabt] Fix wrong-TFM assembly loading -> empty .jlo.xml files#11248jonathanpeppers wants to merge 6 commits intorelease/10.0.1xxfrom
.jlo.xml files#11248jonathanpeppers wants to merge 6 commits intorelease/10.0.1xxfrom
Conversation
Fixes: #10858 In .NET 9, `GenerateJavaStubs` scanned for Java types using `XAJavaTypeScanner.GetJavaTypes`, which called `resolver.Load(asmItem.ItemSpec)` to load each assembly from its exact file path. This ensured the correct TFM version was always used. In ea399ed (#9893), JCW scanning was moved into `AssemblyModifierPipeline` as `FindJavaObjectsStep`. The pipeline's `RunPipeline` method uses `resolver.GetAssembly(source.ItemSpec)`, which strips the path and resolves by assembly **name** through search directories. When a multi-TFM library (e.g. `net11.0;net11.0-android`) is transitively referenced through a `net11.0`-only intermediary, the intermediary's output directory contains a CopyLocal'd `net11.0` copy of the assembly. If that directory appears in the resolver's search path before the correct `net11.0-android` directory, `GetAssembly` loads the wrong version — one without any Android types — producing empty `.jlo.xml` files with 0 JCW types. The fix pre-loads all `ResolvedAssemblies` into the resolver cache from their exact `ItemSpec` paths during resolver setup. This ensures that both `GetAssembly` (which checks the cache first) and Cecil's lazy reference resolution always find the correct TFM version. A regression test `MultiTfmTransitiveReference` reproduces the exact scenario: App -> CoreLib (net11.0) -> MultiTfmLib (net11.0; net11.0-android), where MultiTfmLib has an Android `BroadcastReceiver` behind `#if ANDROID`. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
Contributor
There was a problem hiding this comment.
Pull request overview
Backport to release/10.0.1xx addressing wrong-TFM assembly resolution in AssemblyModifierPipeline, which could cause JCW scanning to load a non-Android assembly variant and generate empty .jlo.xml outputs (issue #10858).
Changes:
- Pre-load all
ResolvedAssembliesintoDirectoryAssemblyResolver’s cache using their exact paths during pipeline setup, soGetAssembly/Cecil lazy resolution consistently finds the correct TFM assembly. - Add a regression test modeling the transitive multi-TFM reference scenario that previously produced empty
.jlo.xmlfiles.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/Xamarin.Android.Build.Tasks/Tasks/AssemblyModifierPipeline.cs | Pre-load resolved assemblies into the resolver cache to prevent wrong-TFM resolution during pipeline execution. |
| src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildWithLibraryTests.cs | Adds a regression test for the multi-TFM transitive reference scenario and updates using directives. |
…ce test Use default Mono runtime instead of parameterizing across all runtimes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Member
Author
|
/azp run |
|
Azure Pipelines could not run because the pipeline triggers exclude this branch/path. |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Member
Author
|
/azp run |
|
Azure Pipelines could not run because the pipeline triggers exclude this branch/path. |
…amework LatestDotNetTargetFramework does not exist on the release/10.0.1xx branch. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The pre-loading approach caused FileNotFoundException for netstandard.dll on the 10.0 branch, where some dependencies (e.g. AppCompat) still target netstandard2.1. Pre-loading ALL assemblies triggered Cecil lazy reference resolution for assemblies that reference netstandard.dll. Instead, use resolver.Load(source.ItemSpec) in RunPipeline to load each assembly from its exact path. This ensures the correct TFM version is loaded without eagerly loading all assemblies upfront. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Backport of #11208 (7bc3bbb) to
release/10.0.1xx.Fixes: #10858
The cherry-pick had a minor conflict in the test file's
usingstatements (the release branch was missingusing Xamarin.Android.Tasks;). Comments referencingnet11.0were updated tonet10.0for this branch.Original PR description:
The fix pre-loads all
ResolvedAssembliesinto the resolver cache from their exactItemSpecpaths during resolver setup. This ensures that bothGetAssembly(which checks the cache first) and Cecil's lazy reference resolution always find the correct TFM version.