Skip to content

Commit dac193e

Browse files
Use documented XA4325 error code for JNI name rewriting failures
Replace the ad-hoc RJN0000/RJN0001 error codes and their hard-coded English strings with a single documented, localizable XA4325 product code. The task prefix stays "RJN" so unexpected exceptions keep reporting as XARJN7xxx, consistent with other task-specific prefixes; only the two explicit errors change. The user-visible detail is resource-backed as well: XA4325 is a general wrapper and the two specific failures live in XA4325_SourceDestinationCount and XA4325_AssemblyFailure, so no new English fragments are formatted into the message from code. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 4160667 commit dac193e

7 files changed

Lines changed: 109 additions & 3 deletions

File tree

Documentation/docs-mobile/TOC.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,8 @@
364364
href: messages/xa4323.md
365365
- name: XA4324
366366
href: messages/xa4324.md
367+
- name: XA4325
368+
href: messages/xa4325.md
367369
- name: "XA5xxx: GCC and toolchain"
368370
items:
369371
- name: "XA5xxx: GCC and toolchain"

Documentation/docs-mobile/messages/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ Either change the value in the AndroidManifest.xml to match the $(SupportedOSPla
254254
+ [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.
255255
+ [XA4323](xa4323.md): Ignoring directory '{directory}' as it does not exist.
256256
+ [XA4324](xa4324.md): [{arch}] Unable to delete source file '{file}'.
257+
+ [XA4325](xa4325.md): Failed to rewrite managed JNI names for R8. {message}
257258

258259
## XA5xxx: GCC and toolchain
259260

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
---
2+
title: .NET for Android error XA4325
3+
description: XA4325 error code
4+
ms.date: 09/01/2026
5+
f1_keywords:
6+
- "XA4325"
7+
---
8+
9+
# .NET for Android error XA4325
10+
11+
## Example messages
12+
13+
```
14+
error XA4325: Failed to rewrite managed JNI names for R8. The 'SourceFiles' and 'DestinationFiles' item groups must contain the same number of items.
15+
```
16+
17+
```
18+
error XA4325: Failed to rewrite managed JNI names for R8. Could not rewrite the JNI names in the assembly 'obj/Release/net11.0-android/android/Acme.App.dll': The file contains no managed metadata.
19+
```
20+
21+
## Issue
22+
23+
When R8 obfuscates Java type and member names, the JNI names embedded in your
24+
managed assemblies must be updated to match the obfuscated names. This error
25+
means that step failed, so the app would not have been able to find its Java
26+
types at run time.
27+
28+
There are two causes:
29+
30+
* **Mismatched item groups.** The `SourceFiles` and `DestinationFiles` item
31+
groups passed to the `RewriteJniNamesForR8` task did not contain the same
32+
number of items. This only happens if a custom target invokes the task
33+
directly, or if a target that produces these item groups has been overridden.
34+
35+
* **An assembly could not be rewritten.** A specific assembly could not be read
36+
or reconstructed. The message names the assembly and includes the underlying
37+
reason, such as the file not containing managed metadata or containing
38+
malformed IL.
39+
40+
## Solution
41+
42+
For the mismatched item groups case, review any custom targets that call
43+
`RewriteJniNamesForR8` and make sure `SourceFiles` and `DestinationFiles` are
44+
populated in matching order, or set `DestinationDirectory` instead of
45+
`DestinationFiles`.
46+
47+
For the assembly failure case, first confirm the named file is a managed
48+
assembly and is not corrupt. Deleting the `bin/` and `obj/` directories and
49+
rebuilding clears a partially written or stale file.
50+
51+
If the named file is a valid managed assembly and the failure persists, this is
52+
unexpected. Please [report an issue][report-issue] and include the full error
53+
message, the name of the assembly, and, if possible, a project that reproduces
54+
the failure.
55+
56+
[report-issue]: https://github.com/dotnet/android/issues/new/choose

src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs

Lines changed: 27 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Xamarin.Android.Build.Tasks/Properties/Resources.resx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,19 @@ Remove the '{0}' reference from your project and add the '{1}' NuGet package ins
884884
<comment>{0} - The target architecture, such as Arm, Arm64, or X86_64
885885
{1} - The path to the source file which could not be deleted.</comment>
886886
</data>
887+
<data name="XA4325" xml:space="preserve">
888+
<value>Failed to rewrite managed JNI names for R8. {0}</value>
889+
<comment>{0} - A sentence describing the specific failure. It is supplied by one of the XA4325_* resources.</comment>
890+
</data>
891+
<data name="XA4325_AssemblyFailure" xml:space="preserve">
892+
<value>Could not rewrite the JNI names in the assembly '{0}': {1}</value>
893+
<comment>{0} - The path of the assembly which could not be rewritten.
894+
{1} - The underlying message describing why the assembly could not be rewritten. It is not localized.</comment>
895+
</data>
896+
<data name="XA4325_SourceDestinationCount" xml:space="preserve">
897+
<value>The 'SourceFiles' and 'DestinationFiles' item groups must contain the same number of items.</value>
898+
<comment>The following are literal MSBuild item group names and should not be translated: 'SourceFiles', 'DestinationFiles'.</comment>
899+
</data>
887900
<data name="XA5101" xml:space="preserve">
888901
<value>Missing Android NDK toolchains directory '{0}'. Please install the Android NDK.</value>
889902
<comment>{0} - The path of the missing directory</comment>

src/Xamarin.Android.Build.Tasks/Tasks/RewriteJniNamesForR8.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public class RewriteJniNamesForR8 : AndroidTask
4646
public override bool RunTask ()
4747
{
4848
if (DestinationDirectory.IsNullOrEmpty () && SourceFiles.Length != DestinationFiles.Length) {
49-
Log.LogCodedError ("RJN0000", "SourceFiles and DestinationFiles must contain the same number of items.");
49+
Log.LogCodedError ("XA4325", Properties.Resources.XA4325, Properties.Resources.XA4325_SourceDestinationCount);
5050
return !Log.HasLoggedErrors;
5151
}
5252

@@ -66,7 +66,8 @@ public override bool RunTask ()
6666
rewritten.SetMetadata ("OriginalItemSpec", source);
6767
rewrittenFiles [i] = rewritten;
6868
} catch (JniRewriteException e) {
69-
Log.LogCodedError ("RJN0001", $"Could not rewrite the JNI names in '{source}': {e.Message}");
69+
Log.LogCodedError ("XA4325", Properties.Resources.XA4325,
70+
string.Format (Properties.Resources.XA4325_AssemblyFailure, source, e.Message));
7071
}
7172
}
7273

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/RewriteJniNamesForR8Tests.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Collections.Immutable;
34
using System.IO;
45
using System.Reflection;
56
using System.Reflection.Metadata;
67
using System.Reflection.Metadata.Ecma335;
78
using System.Reflection.PortableExecutable;
9+
using Microsoft.Build.Framework;
810
using NUnit.Framework;
911
using Xamarin.Android.Tasks;
1012

@@ -116,14 +118,18 @@ public void FailsWithACodedErrorWhenSourceAndDestinationCountsDiffer ()
116118
string mappingFile = Path.Combine (path, "mapping.txt");
117119
File.WriteAllText (mappingFile, "");
118120

121+
var errors = new List<BuildErrorEventArgs> ();
119122
var task = new RewriteJniNamesForR8 {
120-
BuildEngine = new MockBuildEngine (TestContext.Out),
123+
BuildEngine = new MockBuildEngine (TestContext.Out, errors),
121124
SourceFiles = new [] { new Microsoft.Build.Utilities.TaskItem ("a.dll"), new Microsoft.Build.Utilities.TaskItem ("b.dll") },
122125
DestinationFiles = new [] { new Microsoft.Build.Utilities.TaskItem ("a.dll") },
123126
MappingFile = mappingFile,
124127
};
125128

126129
Assert.IsFalse (task.Execute (), "Task should fail when SourceFiles/DestinationFiles counts differ.");
130+
Assert.AreEqual (1, errors.Count, "Exactly one error should have been logged.");
131+
Assert.AreEqual ("XA4325", errors [0].Code, "The error should use the documented XA4325 code.");
132+
StringAssert.Contains ("SourceFiles", errors [0].Message, "The error should name the mismatched item groups.");
127133
}
128134

129135
[Test]

0 commit comments

Comments
 (0)