Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
a7cae21
[runtime] Extend JNI remapping support
simonrozsival Sep 21, 2026
0fb6aef
[runtime] Address JNI remapping review feedback
simonrozsival Sep 21, 2026
7e70f4d
[runtime] Keep JNI remapping lookups managed
simonrozsival Sep 22, 2026
b148054
[Java.Interop] Preserve instance remap braces
simonrozsival Sep 22, 2026
c329fdb
[runtime] Address managed remapping review
simonrozsival Sep 22, 2026
f56ffa8
[Java.Interop] Dispose unpublished member cache entries
simonrozsival Sep 22, 2026
cc22754
[runtime] Fix managed field remapping tests
simonrozsival Sep 22, 2026
3feea2c
[NativeAOT] Initialize JNI remapping data
simonrozsival Sep 23, 2026
a41889d
[tests] Update JNI remapping APK baselines
simonrozsival Sep 24, 2026
b8b5d28
[runtime] Reverse-map incoming JNI peers
simonrozsival Sep 25, 2026
40fc08b
[runtime] Preserve explicit JNI registrations
simonrozsival Sep 25, 2026
bd51ec9
[runtime] Reconcile native runtime cleanup
simonrozsival Sep 27, 2026
ace3b11
[runtime] Preserve one-hop JNI remapping
simonrozsival Sep 28, 2026
39004c2
[runtime] Trim unused JNI remapping support
simonrozsival Sep 28, 2026
da21fa4
Merge main into JNI remapping runtime
simonrozsival Sep 30, 2026
2ee61b1
[tests] Refresh Simple CoreCLR APK size baselines
simonrozsival Sep 30, 2026
ed95506
Merge main into JNI remapping runtime
simonrozsival Sep 30, 2026
7b7e417
[Xamarin.Android.Build.Tasks] Generate R8 JNI remapping tables
simonrozsival Sep 21, 2026
0e11489
[Xamarin.Android.Build.Tasks] Address R8 remapping review feedback
simonrozsival Sep 23, 2026
eca84da
[Xamarin.Android.Build.Tasks] Resolve R8 diagnostic code collision
simonrozsival Sep 30, 2026
072be4a
[Xamarin.Android.Build.Tasks] Fail closed when scanning R8 inputs
simonrozsival Sep 30, 2026
5dcdc94
[docs] Fix R8 message formatting
simonrozsival Sep 30, 2026
5e30ffe
Merge main into JNI remapping runtime
simonrozsival Oct 1, 2026
855c948
Merge latest JNI remapping runtime parent
simonrozsival Oct 1, 2026
d844ee4
[Xamarin.Android.Build.Tasks] Generate R8 JNI remapping tables
simonrozsival Sep 21, 2026
8ef8fda
[Xamarin.Android.Build.Tasks] Address R8 remapping review feedback
simonrozsival Sep 23, 2026
ce4baf2
[Xamarin.Android.Build.Tasks] Resolve R8 diagnostic code collision
simonrozsival Sep 30, 2026
a96851c
[Xamarin.Android.Build.Tasks] Fail closed when scanning R8 inputs
simonrozsival Sep 30, 2026
5581293
[docs] Fix R8 message formatting
simonrozsival Sep 30, 2026
7f164c1
Merge commit '5581293b76dc5d5da426974691141b877da2a6ed' into simonroz…
simonrozsival Oct 1, 2026
afecd5e
[Xamarin.Android.Build.Tasks] Read surviving R8 types from metadata
simonrozsival Oct 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Documentation/docs-mobile/TOC.yml
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,10 @@
href: messages/xa4323.md
- name: XA4324
href: messages/xa4324.md
- name: XA4325
href: messages/xa4325.md
- name: XA4326
href: messages/xa4326.md
- name: XA4327
href: messages/xa4327.md
- name: XA4328
Expand Down
2 changes: 2 additions & 0 deletions Documentation/docs-mobile/messages/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,8 @@ Either change the value in the AndroidManifest.xml to match the $(SupportedOSPla
+ [XA4322](xa4322.md): Skipping library ProGuard configuration file '{file}' (from {source}) because it contains the unsupported global option '{option}'. Global ProGuard options are only allowed in application projects.
+ [XA4323](xa4323.md): Ignoring directory '{directory}' as it does not exist.
+ [XA4324](xa4324.md): [{arch}] Unable to delete source file '{file}'.
+ [XA4325](xa4325.md): Failed to generate the R8 JNI remapping data. {0}
+ [XA4326](xa4326.md): The R8 JNI remapping data is incomplete. {0}
+ [XA4327](xa4327.md): Could not extract Java type map keys from '{0}': {1}
+ [XA4328](xa4328.md): Could not generate typemap ProGuard configuration from '{0}': {1}

Expand Down
29 changes: 29 additions & 0 deletions Documentation/docs-mobile/messages/xa4325.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
title: .NET for Android error XA4325
description: XA4325 error code
ms.date: 09/30/2026
f1_keywords:
- "XA4325"
---

# .NET for Android error XA4325

## Example message

```
error XA4325: Failed to generate the R8 JNI remapping data. The R8 mapping file 'mapping.txt' was not found.
```

## Issue

The build could not generate runtime JNI remapping data from the final R8
mapping. The mapping, linked managed metadata, or NativeAOT retention object
is missing, unreadable, malformed, or contains entries that cannot be
represented unambiguously by the runtime lookup tables.

## Solution

Fix the reported input path or earlier build failure. If the files were
generated by .NET for Android, clean and rebuild the application. If the
error reports ambiguous entries, use R8 keep rules so the affected Java
classes or members are not merged into the same runtime lookup key.
28 changes: 28 additions & 0 deletions Documentation/docs-mobile/messages/xa4326.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
title: .NET for Android warning XA4326
description: XA4326 warning code
ms.date: 09/30/2026
f1_keywords:
- "XA4326"
---

# .NET for Android warning XA4326

## Example message

```
warning XA4326: The R8 JNI remapping data is incomplete. The entry for 'example/Peer.run' was not emitted.
```

## Issue

The build omitted an R8 JNI remapping entry because another remapping input
already owns the same lookup key, or because a Java member signature could
not be converted to a JNI descriptor. The runtime remapping data can
therefore be incomplete for the affected type or member.

## Solution

Review the reported remapping inputs and Java signature. Remove conflicting
custom remapping entries, correct malformed signatures, or add R8 keep rules
for the affected Java type or member.
102 changes: 102 additions & 0 deletions src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

87 changes: 87 additions & 0 deletions src/Xamarin.Android.Build.Tasks/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,93 @@ Remove the '{0}' reference from your project and add the '{1}' NuGet package ins
<value>[{0}] Unable to delete source file '{1}'</value>
<comment>{0} - The target architecture, such as Arm, Arm64, or X86_64
{1} - The path to the source file which could not be deleted.</comment>
</data>
<data name="XA4325" xml:space="preserve">
<value>Failed to generate the R8 JNI remapping data. {0}</value>
<comment>The following are literal names and should not be translated: R8, JNI.
{0} - A sentence describing the specific failure.</comment>
</data>
<data name="XA4325_MappingNotFound" xml:space="preserve">
<value>The R8 mapping file '{0}' was not found.</value>
<comment>The following is a literal name and should not be translated: R8.
{0} - The path of the missing mapping file.</comment>
</data>
<data name="XA4325_MappingDataFailure" xml:space="preserve">
<value>The R8 mapping file '{0}' could not be read: {1}</value>
<comment>The following is a literal name and should not be translated: R8.
{0} - The path of the mapping file.
{1} - The exception message.</comment>
</data>
<data name="XA4325_AssemblyReadFailure" xml:space="preserve">
<value>The linked managed assembly '{0}' could not be read: {1}</value>
<comment>{0} - The path of the managed assembly.
{1} - The exception message.</comment>
</data>
<data name="XA4325_AssemblyNotFound" xml:space="preserve">
<value>The linked managed assembly '{0}' was not found.</value>
<comment>{0} - The path of the missing managed assembly.</comment>
</data>
<data name="XA4325_AssemblyHasNoMetadata" xml:space="preserve">
<value>The linked managed assembly '{0}' does not contain managed metadata.</value>
<comment>{0} - The path of the input file.</comment>
</data>
<data name="XA4325_AmbiguousEntry" xml:space="preserve">
<value>The generated '{0}' entries for '{1}' have conflicting runtime targets '{2}' and '{3}', which cannot be represented by the JNI remapping tables.</value>
<comment>The following is a literal name and should not be translated: JNI.
{0} - The XML element name.
{1} - The runtime lookup key.
{2} - The first target.
{3} - The conflicting target.</comment>
</data>
<data name="XA4325_NativeAotObjectRequired" xml:space="preserve">
<value>NativeAOT JNI retention requires an existing post-ILC NativeAotObjectFile; '{0}' was not found.</value>
<comment>The following are literal names and should not be translated: NativeAOT, JNI, ILC, NativeAotObjectFile.
{0} - The path of the missing ILC native object, or an empty string if none was supplied.</comment>
</data>
<data name="XA4325_NativeAotObjectReadFailure" xml:space="preserve">
<value>The NativeAOT retention object '{0}' could not be read: {1}</value>
<comment>The following is a literal name and should not be translated: NativeAOT.
{0} - The path of the ILC native object.
{1} - The exception message.</comment>
</data>
<data name="XA4325_NativeAotModeRequired" xml:space="preserve">
<value>NativeAotObjectFile requires NativeAot=true.</value>
<comment>The following are literal names and should not be translated: NativeAotObjectFile, NativeAot=true.</comment>
</data>
<data name="XA4325_NativeAotObjectFormat" xml:space="preserve">
<value>Expected a 32-bit or 64-bit little-endian relocatable NativeAOT ELF object.</value>
<comment>The following are literal names and should not be translated: NativeAOT, ELF.</comment>
</data>
<data name="XA4325_NativeAotInvalidSection" xml:space="preserve">
<value>The NativeAOT ELF object contains an invalid section extent.</value>
<comment>The following are literal names and should not be translated: NativeAOT, ELF.</comment>
</data>
<data name="XA4325_NativeAotTruncatedSection" xml:space="preserve">
<value>The NativeAOT ELF object contains truncated section data.</value>
<comment>The following are literal names and should not be translated: NativeAOT, ELF.</comment>
</data>
<data name="XA4325_NativeAotMissingSections" xml:space="preserve">
<value>The NativeAOT object must contain allocated __managedcode and initialized data sections.</value>
<comment>The following are literal names and should not be translated: NativeAOT, __managedcode.</comment>
</data>
<data name="XA4326" xml:space="preserve">
<value>The R8 JNI remapping data is incomplete. {0}</value>
<comment>The following are literal names and should not be translated: R8, JNI.
{0} - A sentence describing the specific omission.</comment>
</data>
<data name="XA4326_ConflictingEntry" xml:space="preserve">
<value>The '{0}' entry for '{1}' was not emitted: another JNI remapping input already maps it to '{2}', which conflicts with '{3}'.</value>
<comment>The following is a literal name and should not be translated: JNI.
{0} - The XML element name.
{1} - The source lookup key.
{2} - The existing target.
{3} - The generated target.</comment>
</data>
<data name="XA4326_UnsupportedSignature" xml:space="preserve">
<value>The entry for '{0}' was not emitted: its signature '{1}' could not be converted to a JNI descriptor.</value>
<comment>The following is a literal name and should not be translated: JNI.
{0} - The member the entry describes.
{1} - The Java signature which could not be converted.</comment>
</data>
<data name="XA4327" xml:space="preserve">
<value>Could not extract Java type map keys from '{0}': {1}</value>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public override bool RunTask ()

void GenerateEmpty ()
{
Generate (new JniRemappingAssemblyGenerator (Log));
Generate (new JniRemappingNativeCodeGenerator (Log));
}

void Generate (string remappingXmlFilePath)
Expand All @@ -86,10 +86,10 @@ void Generate (string remappingXmlFilePath)
}
}

Generate (new JniRemappingAssemblyGenerator (Log, typeReplacements, reverseTypeReplacements, methodReplacements, fieldReplacements));
Generate (new JniRemappingNativeCodeGenerator (Log, typeReplacements, reverseTypeReplacements, methodReplacements, fieldReplacements));
}

void Generate (JniRemappingAssemblyGenerator jniRemappingComposer)
void Generate (JniRemappingNativeCodeGenerator jniRemappingComposer)
{
LLVMIR.LlvmIrModule module = jniRemappingComposer.Construct ();

Expand Down Expand Up @@ -146,7 +146,6 @@ void ReadXml (XmlReader reader, List<JniRemappingTypeReplacement> typeReplacemen
if (!haveAllAttributes) {
continue;
}

reverseTypeReplacements.Add (new JniRemappingTypeReplacement (from, to));
} else if (MonoAndroidHelper.StringEquals ("replace-method", reader.LocalName)) {
haveAllAttributes &= GetRequiredAttribute ("source-type", out string sourceType);
Expand All @@ -164,10 +163,10 @@ void ReadXml (XmlReader reader, List<JniRemappingTypeReplacement> typeReplacemen
continue;
}

string sourceMethodSignature = reader.GetAttribute ("source-method-signature");
string sourceMethodSignature = reader.GetAttribute ("source-method-signature") ?? "";
// Optional: inputs which predate it (for example the Intune/MAM mapping) keep
// the source signature on the target method.
string targetMethodSignature = reader.GetAttribute ("target-method-signature");
string? targetMethodSignature = reader.GetAttribute ("target-method-signature");
methodReplacements.Add (
new JniRemappingMethodReplacement (
sourceType, sourceMethodName, sourceMethodSignature,
Expand All @@ -179,13 +178,12 @@ void ReadXml (XmlReader reader, List<JniRemappingTypeReplacement> typeReplacemen
haveAllAttributes &= GetRequiredAttribute ("source-field-name", out string sourceFieldName);
haveAllAttributes &= GetRequiredAttribute ("target-type", out string targetType);
haveAllAttributes &= GetRequiredAttribute ("target-field-name", out string targetFieldName);

if (!haveAllAttributes) {
continue;
}

string sourceFieldSignature = reader.GetAttribute ("source-field-signature");
string targetFieldSignature = reader.GetAttribute ("target-field-signature");
string sourceFieldSignature = reader.GetAttribute ("source-field-signature") ?? "";
string? targetFieldSignature = reader.GetAttribute ("target-field-signature");
fieldReplacements.Add (
new JniRemappingFieldReplacement (
sourceType, sourceFieldName, sourceFieldSignature,
Expand Down
Loading