From ca9c909fbcded4b7794b2027b1c99fce4d839a87 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 23 Jan 2026 19:29:03 +0000
Subject: [PATCH 1/6] Initial plan
From 264f73e44c05e55ff5a6a9e203e5e30529c9b1a8 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 23 Jan 2026 20:07:44 +0000
Subject: [PATCH 2/6] Add proper MSBuild error (XA4238) for JCW XML import
failures
Co-authored-by: jonathanpeppers <840039+jonathanpeppers@users.noreply.github.com>
---
.../Properties/Resources.Designer.cs | 9 +++++++++
.../Properties/Resources.resx | 6 ++++++
.../Tasks/GenerateJavaCallableWrappers.cs | 8 +++++++-
3 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs b/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs
index c301a8d6dd6..20ecbfc9ae6 100644
--- a/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs
+++ b/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs
@@ -1300,6 +1300,15 @@ public static string XA4237 {
}
}
+ ///
+ /// Looks up a localized string similar to Could not load Java callable wrapper XML file '{0}': {1}.
+ ///
+ public static string XA4238 {
+ get {
+ return ResourceManager.GetString("XA4238", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Unknown Maven repository: '{0}'..
///
diff --git a/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx b/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx
index 756007eea2a..9f200be92a6 100644
--- a/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx
+++ b/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx
@@ -974,6 +974,12 @@ To use a custom JDK path for a command line build, set the 'JavaSdkDirectory' MS
{0} - Maven artifact id
{1} - The HttpClient reported download exception message
+
+
+ Could not load Java callable wrapper XML file '{0}': {1}
+ The following are literal names and should not be translated: Java callable wrapper, XML.
+{0} - Path to XML file
+{1} - Exception message
Unknown Maven repository: '{0}'.
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaCallableWrappers.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaCallableWrappers.cs
index ca59e949238..d7a1f6b5162 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaCallableWrappers.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaCallableWrappers.cs
@@ -69,7 +69,13 @@ void GenerateWrappers (List assemblies)
return;
}
- var xml = JavaObjectsXmlFile.Import (wrappersPath, JavaObjectsXmlFileReadType.JavaCallableWrappers);
+ JavaObjectsXmlFile xml;
+ try {
+ xml = JavaObjectsXmlFile.Import (wrappersPath, JavaObjectsXmlFileReadType.JavaCallableWrappers);
+ } catch (InvalidOperationException ex) {
+ Log.LogCodedError ("XA4238", Properties.Resources.XA4238, wrappersPath, ex.Message);
+ return;
+ }
if (xml.JavaCallableWrappers.Count == 0) {
Log.LogDebugMessage ($"'{wrappersPath}' is empty, skipping.");
From 25c088a24d9811f14285ce9b625ecd18a555ddae Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 23 Jan 2026 20:49:13 +0000
Subject: [PATCH 3/6] Add test for XA4238 error when Register attribute has no
package
Co-authored-by: jonathanpeppers <840039+jonathanpeppers@users.noreply.github.com>
---
.../InvalidConfigTests.cs | 25 +++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/InvalidConfigTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/InvalidConfigTests.cs
index d7499a67874..381fc7ac573 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/InvalidConfigTests.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/InvalidConfigTests.cs
@@ -119,5 +119,30 @@ public void XA0119Interpreter ()
Assert.IsTrue (StringAssertEx.ContainsText (builder.LastBuildOutput, "XA0119"), "Output should contain XA0119 warnings");
}
}
+
+ [Test]
+ public void XA4238 ()
+ {
+ var proj = new XamarinAndroidApplicationProject ();
+ proj.Sources.Add (new BuildItem ("Compile", "CustomView.cs") { TextContent = () => @"
+using Android.Content;
+using Android.Runtime;
+using Android.Views;
+
+namespace UnnamedProject
+{
+ // Register attribute without package prefix should cause XA4238
+ [Register(""CustomView"")]
+ public class CustomView : View
+ {
+ public CustomView (Context context) : base (context) { }
+ }
+}" });
+ using (var builder = CreateApkBuilder ()) {
+ builder.ThrowOnBuildFailure = false;
+ Assert.IsFalse (builder.Build (proj), "Build should have failed.");
+ Assert.IsTrue (StringAssertEx.ContainsText (builder.LastBuildOutput, "XA4238"), "Output should contain XA4238 error");
+ }
+ }
}
}
From 4e0371492dfbd4a74cf6b9121d310526fc49126d Mon Sep 17 00:00:00 2001
From: Jonathan Peppers
Date: Mon, 26 Jan 2026 16:18:18 -0600
Subject: [PATCH 4/6] Bump java.interop
---
Configuration.props | 2 +-
external/Java.Interop | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Configuration.props b/Configuration.props
index c5c6b0c7e8f..225f8abc850 100644
--- a/Configuration.props
+++ b/Configuration.props
@@ -146,7 +146,7 @@
$([System.IO.Path]::GetFullPath ('$(LibUnwindSourceDirectory)'))
$([System.IO.Path]::GetFullPath ('$(LibUnwindGeneratedHeadersDirectory)'))
$([System.IO.Path]::GetFullPath ('$(LZ4SourceDirectory)'))
- net9.0
+ net10.0
$(AndroidSdkFullPath)\platform-tools\
diff --git a/external/Java.Interop b/external/Java.Interop
index faee0da184d..b7965d4ccf7 160000
--- a/external/Java.Interop
+++ b/external/Java.Interop
@@ -1 +1 @@
-Subproject commit faee0da184d57f9c3f158b4a78b7109e453f97a6
+Subproject commit b7965d4ccf7dd5785a930dcc4b1854d2614a654b
From 64f84fe91fd6336a7839eb28a3437d20cb29cf19 Mon Sep 17 00:00:00 2001
From: Jonathan Peppers
Date: Mon, 26 Jan 2026 16:18:24 -0600
Subject: [PATCH 5/6] Revert "Add proper MSBuild error (XA4238) for JCW XML
import failures"
This reverts commit 264f73e44c05e55ff5a6a9e203e5e30529c9b1a8.
---
.../Properties/Resources.Designer.cs | 9 ---------
.../Properties/Resources.resx | 6 ------
.../Tasks/GenerateJavaCallableWrappers.cs | 8 +-------
3 files changed, 1 insertion(+), 22 deletions(-)
diff --git a/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs b/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs
index 20ecbfc9ae6..c301a8d6dd6 100644
--- a/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs
+++ b/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs
@@ -1300,15 +1300,6 @@ public static string XA4237 {
}
}
- ///
- /// Looks up a localized string similar to Could not load Java callable wrapper XML file '{0}': {1}.
- ///
- public static string XA4238 {
- get {
- return ResourceManager.GetString("XA4238", resourceCulture);
- }
- }
-
///
/// Looks up a localized string similar to Unknown Maven repository: '{0}'..
///
diff --git a/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx b/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx
index 9f200be92a6..756007eea2a 100644
--- a/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx
+++ b/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx
@@ -974,12 +974,6 @@ To use a custom JDK path for a command line build, set the 'JavaSdkDirectory' MS
{0} - Maven artifact id
{1} - The HttpClient reported download exception message
-
-
- Could not load Java callable wrapper XML file '{0}': {1}
- The following are literal names and should not be translated: Java callable wrapper, XML.
-{0} - Path to XML file
-{1} - Exception message
Unknown Maven repository: '{0}'.
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaCallableWrappers.cs b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaCallableWrappers.cs
index d7a1f6b5162..ca59e949238 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaCallableWrappers.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaCallableWrappers.cs
@@ -69,13 +69,7 @@ void GenerateWrappers (List assemblies)
return;
}
- JavaObjectsXmlFile xml;
- try {
- xml = JavaObjectsXmlFile.Import (wrappersPath, JavaObjectsXmlFileReadType.JavaCallableWrappers);
- } catch (InvalidOperationException ex) {
- Log.LogCodedError ("XA4238", Properties.Resources.XA4238, wrappersPath, ex.Message);
- return;
- }
+ var xml = JavaObjectsXmlFile.Import (wrappersPath, JavaObjectsXmlFileReadType.JavaCallableWrappers);
if (xml.JavaCallableWrappers.Count == 0) {
Log.LogDebugMessage ($"'{wrappersPath}' is empty, skipping.");
From cbe8edce943de7d640d56dbc0fd988560ff2c60d Mon Sep 17 00:00:00 2001
From: Jonathan Peppers
Date: Mon, 26 Jan 2026 16:20:35 -0600
Subject: [PATCH 6/6] Rework test
---
.../Xamarin.Android.Build.Tests/BuildTest.cs | 22 ++++++++++++++++
.../InvalidConfigTests.cs | 25 -------------------
2 files changed, 22 insertions(+), 25 deletions(-)
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs
index 0781e03330e..481891ecb2e 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs
@@ -2212,5 +2212,27 @@ public void SystemIOHashing ([Values] AndroidRuntime runtime)
using var builder = CreateApkBuilder ();
Assert.IsTrue (builder.Build (proj), "build should have succeeded.");
}
+
+ [Test]
+ public void CustomView_NoPackage ()
+ {
+ var proj = new XamarinAndroidApplicationProject ();
+ proj.Sources.Add (new BuildItem ("Compile", "CustomView.cs") { TextContent = () => @"
+using Android.Content;
+using Android.Runtime;
+using Android.Views;
+
+namespace UnnamedProject
+{
+ // Register attribute without package prefix should cause XA4238
+ [Register(""CustomView"")]
+ public class CustomView : View
+ {
+ public CustomView (Context context) : base (context) { }
+ }
+}" });
+ using var builder = CreateApkBuilder ();
+ Assert.IsTrue (builder.Build (proj), "Build should have succeeded.");
+ }
}
}
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/InvalidConfigTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/InvalidConfigTests.cs
index 381fc7ac573..d7499a67874 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/InvalidConfigTests.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/InvalidConfigTests.cs
@@ -119,30 +119,5 @@ public void XA0119Interpreter ()
Assert.IsTrue (StringAssertEx.ContainsText (builder.LastBuildOutput, "XA0119"), "Output should contain XA0119 warnings");
}
}
-
- [Test]
- public void XA4238 ()
- {
- var proj = new XamarinAndroidApplicationProject ();
- proj.Sources.Add (new BuildItem ("Compile", "CustomView.cs") { TextContent = () => @"
-using Android.Content;
-using Android.Runtime;
-using Android.Views;
-
-namespace UnnamedProject
-{
- // Register attribute without package prefix should cause XA4238
- [Register(""CustomView"")]
- public class CustomView : View
- {
- public CustomView (Context context) : base (context) { }
- }
-}" });
- using (var builder = CreateApkBuilder ()) {
- builder.ThrowOnBuildFailure = false;
- Assert.IsFalse (builder.Build (proj), "Build should have failed.");
- Assert.IsTrue (StringAssertEx.ContainsText (builder.LastBuildOutput, "XA4238"), "Output should contain XA4238 error");
- }
- }
}
}