From 14546190e9aab2ee4471db49da16bb09fcb0726d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 1 Jun 2026 10:06:22 +0000 Subject: [PATCH 1/7] Initial plan From bee6f1f58c8e77d44a9a06e531e2e74dd719d954 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 1 Jun 2026 10:38:01 +0000 Subject: [PATCH 2/7] Fix BuildArchive jar entry retention Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com> --- .../Tasks/BuildArchive.cs | 1 + .../Tasks/BuildArchiveTests.cs | 66 +++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/BuildArchive.cs b/src/Xamarin.Android.Build.Tasks/Tasks/BuildArchive.cs index d1fd2af0f67..14b365cae7a 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/BuildArchive.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/BuildArchive.cs @@ -158,6 +158,7 @@ public override bool RunTask () // ItemSpec for these will be "# // eg: "obj/myjar.jar#myfile.txt" var jar_file_path = disk_path.Substring (0, disk_path.Length - (jar_entry_name.Length + 1)); + existingEntries.Remove (apk_path); if (apk.ContainsEntry (apk_path)) { Log.LogDebugMessage ("Failed to add jar entry {0} from {1}: the same file already exists in the apk", jar_entry_name, Path.GetFileName (jar_file_path)); diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs new file mode 100644 index 00000000000..4b0cfde236b --- /dev/null +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs @@ -0,0 +1,66 @@ +using System.IO; +using System.Text; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using NUnit.Framework; +using Xamarin.Android.Tasks; +using Xamarin.Tools.Zip; + +namespace Xamarin.Android.Build.Tests +{ + [TestFixture] + public class BuildArchiveTests + { + string tempDirectory; + + [SetUp] + public void Setup () + { + tempDirectory = Path.Combine (Path.GetTempPath (), Path.GetRandomFileName ()); + Directory.CreateDirectory (tempDirectory); + } + + [TearDown] + public void TearDown () + { + Directory.Delete (tempDirectory, recursive: true); + } + + [Test] + public void ExistingJavaArchiveEntriesAreRetained () + { + var apk = Path.Combine (tempDirectory, "app.apk"); + var jar = Path.Combine (tempDirectory, "classes.jar"); + + CreateArchive (apk, ("commonMain/default/manifest", "existing"), ("stale.txt", "stale")); + CreateArchive (jar, ("commonMain/default/manifest", "current")); + + var item = new TaskItem ($"{jar}#commonMain/default/manifest"); + item.SetMetadata ("ArchivePath", "commonMain/default/manifest"); + item.SetMetadata ("JavaArchiveEntry", "commonMain/default/manifest"); + + var task = new BuildArchive { + BuildEngine = new MockBuildEngine (TestContext.Out), + ApkOutputPath = apk, + FilesToAddToArchive = new ITaskItem [] { item }, + }; + + Assert.IsTrue (task.RunTask (), "task should have succeeded"); + + using (var archive = ZipArchive.Open (apk, FileMode.Open)) { + archive.AssertEntryContents (apk, "commonMain/default/manifest", "existing"); + archive.AssertDoesNotContainEntry (apk, "stale.txt"); + } + } + + static void CreateArchive (string path, params (string name, string contents) [] entries) + { + using (var stream = File.Create (path)) + using (var archive = ZipArchive.Create (stream)) { + foreach (var entry in entries) { + archive.AddEntry (entry.name, entry.contents, encoding: Encoding.UTF8); + } + } + } + } +} From 95e7370234f2a6adc116113fd0b8540bc2543951 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 1 Jun 2026 12:01:39 +0000 Subject: [PATCH 3/7] Update stale BuildArchive jar entries Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com> --- .../Tasks/BuildArchive.cs | 21 +++++++++++++------ .../Tasks/BuildArchiveTests.cs | 4 ++-- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/BuildArchive.cs b/src/Xamarin.Android.Build.Tasks/Tasks/BuildArchive.cs index 14b365cae7a..4a752613c3c 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/BuildArchive.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/BuildArchive.cs @@ -158,17 +158,26 @@ public override bool RunTask () // ItemSpec for these will be "# // eg: "obj/myjar.jar#myfile.txt" var jar_file_path = disk_path.Substring (0, disk_path.Length - (jar_entry_name.Length + 1)); - existingEntries.Remove (apk_path); - - if (apk.ContainsEntry (apk_path)) { - Log.LogDebugMessage ("Failed to add jar entry {0} from {1}: the same file already exists in the apk", jar_entry_name, Path.GetFileName (jar_file_path)); - continue; - } + var wasExistingOutputEntry = existingEntries.Remove (apk_path); using (var stream = File.OpenRead (jar_file_path)) using (var jar = ZipArchive.Open (stream)) { var jar_item = jar.ReadEntry (jar_entry_name); + if (apk.ContainsEntry (apk_path)) { + if (!wasExistingOutputEntry) { + Log.LogDebugMessage ("Failed to add jar entry {0} from {1}: the same file already exists in the apk", jar_entry_name, Path.GetFileName (jar_file_path)); + continue; + } + + if (apk.GetEntry (apk_path).CRC == jar_item.CRC) { + Log.LogDebugMessage ("Skipping {0} from {1} as it is up to date.", jar_entry_name, jar_file_path); + continue; + } + + apk.DeleteEntry (apk_path); + } + byte [] data; var d = MemoryStreamPool.Shared.Rent (); diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs index 4b0cfde236b..ceba4889a64 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs @@ -27,7 +27,7 @@ public void TearDown () } [Test] - public void ExistingJavaArchiveEntriesAreRetained () + public void ExistingJavaArchiveEntriesAreUpdated () { var apk = Path.Combine (tempDirectory, "app.apk"); var jar = Path.Combine (tempDirectory, "classes.jar"); @@ -48,7 +48,7 @@ public void ExistingJavaArchiveEntriesAreRetained () Assert.IsTrue (task.RunTask (), "task should have succeeded"); using (var archive = ZipArchive.Open (apk, FileMode.Open)) { - archive.AssertEntryContents (apk, "commonMain/default/manifest", "existing"); + archive.AssertEntryContents (apk, "commonMain/default/manifest", "current"); archive.AssertDoesNotContainEntry (apk, "stale.txt"); } } From 2c430e7de6ff4e4c9b4a01dcc4a31318087aba40 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 1 Jun 2026 12:07:58 +0000 Subject: [PATCH 4/7] Cover up-to-date BuildArchive jar entries Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com> --- .../Tasks/BuildArchiveTests.cs | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs index ceba4889a64..2fc98ba96a0 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.IO; using System.Text; using Microsoft.Build.Framework; @@ -53,6 +54,35 @@ public void ExistingJavaArchiveEntriesAreUpdated () } } + [Test] + public void ExistingJavaArchiveEntriesAreSkippedWhenUpToDate () + { + var apk = Path.Combine (tempDirectory, "app.apk"); + var jar = Path.Combine (tempDirectory, "classes.jar"); + + CreateArchive (apk, ("commonMain/default/manifest", "current")); + CreateArchive (jar, ("commonMain/default/manifest", "current")); + + var item = new TaskItem ($"{jar}#commonMain/default/manifest"); + item.SetMetadata ("ArchivePath", "commonMain/default/manifest"); + item.SetMetadata ("JavaArchiveEntry", "commonMain/default/manifest"); + var messages = new List (); + + var task = new BuildArchive { + BuildEngine = new MockBuildEngine (TestContext.Out, messages: messages), + ApkOutputPath = apk, + FilesToAddToArchive = new ITaskItem [] { item }, + }; + + Assert.IsTrue (task.RunTask (), "task should have succeeded"); + + Assert.That (messages, Has.Some.Property (nameof (BuildMessageEventArgs.Message)).EqualTo ($"Skipping commonMain/default/manifest from {jar} as it is up to date.")); + + using (var archive = ZipArchive.Open (apk, FileMode.Open)) { + archive.AssertEntryContents (apk, "commonMain/default/manifest", "current"); + } + } + static void CreateArchive (string path, params (string name, string contents) [] entries) { using (var stream = File.Create (path)) From c1168b1898cb44e632e003987313787f41a142a0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 2 Jun 2026 12:54:30 +0000 Subject: [PATCH 5/7] Address BuildArchive review feedback Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com> --- .../Tasks/BuildArchive.cs | 13 +- .../Tasks/BuildArchiveTests.cs | 165 +++++++++++------- 2 files changed, 109 insertions(+), 69 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/BuildArchive.cs b/src/Xamarin.Android.Build.Tasks/Tasks/BuildArchive.cs index 4a752613c3c..75aae5d7aa4 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/BuildArchive.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/BuildArchive.cs @@ -159,17 +159,18 @@ public override bool RunTask () // eg: "obj/myjar.jar#myfile.txt" var jar_file_path = disk_path.Substring (0, disk_path.Length - (jar_entry_name.Length + 1)); var wasExistingOutputEntry = existingEntries.Remove (apk_path); + var hasApkEntry = apk.ContainsEntry (apk_path); + + if (hasApkEntry && !wasExistingOutputEntry) { + Log.LogDebugMessage ("Failed to add jar entry {0} from {1}: the same file already exists in the apk", jar_entry_name, Path.GetFileName (jar_file_path)); + continue; + } using (var stream = File.OpenRead (jar_file_path)) using (var jar = ZipArchive.Open (stream)) { var jar_item = jar.ReadEntry (jar_entry_name); - if (apk.ContainsEntry (apk_path)) { - if (!wasExistingOutputEntry) { - Log.LogDebugMessage ("Failed to add jar entry {0} from {1}: the same file already exists in the apk", jar_entry_name, Path.GetFileName (jar_file_path)); - continue; - } - + if (hasApkEntry) { if (apk.GetEntry (apk_path).CRC == jar_item.CRC) { Log.LogDebugMessage ("Skipping {0} from {1} as it is up to date.", jar_entry_name, jar_file_path); continue; diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs index 2fc98ba96a0..f5d031aae80 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs @@ -1,3 +1,5 @@ +#nullable enable +using System; using System.Collections.Generic; using System.IO; using System.Text; @@ -7,89 +9,126 @@ using Xamarin.Android.Tasks; using Xamarin.Tools.Zip; -namespace Xamarin.Android.Build.Tests +namespace Xamarin.Android.Build.Tests; + +[TestFixture] +public class BuildArchiveTests { - [TestFixture] - public class BuildArchiveTests - { - string tempDirectory; + string? tempDirectory; - [SetUp] - public void Setup () - { - tempDirectory = Path.Combine (Path.GetTempPath (), Path.GetRandomFileName ()); - Directory.CreateDirectory (tempDirectory); - } + string TempDirectory => tempDirectory ?? throw new InvalidOperationException ("Setup has not run."); + + [SetUp] + public void Setup () + { + tempDirectory = Path.Combine (Path.GetTempPath (), Path.GetRandomFileName ()); + Directory.CreateDirectory (tempDirectory); + } - [TearDown] - public void TearDown () - { + [TearDown] + public void TearDown () + { + if (tempDirectory != null && Directory.Exists (tempDirectory)) Directory.Delete (tempDirectory, recursive: true); - } + } - [Test] - public void ExistingJavaArchiveEntriesAreUpdated () - { - var apk = Path.Combine (tempDirectory, "app.apk"); - var jar = Path.Combine (tempDirectory, "classes.jar"); + [Test] + public void ExistingJavaArchiveEntriesAreUpdated () + { + var apk = Path.Combine (TempDirectory, "app.apk"); + var jar = Path.Combine (TempDirectory, "classes.jar"); - CreateArchive (apk, ("commonMain/default/manifest", "existing"), ("stale.txt", "stale")); - CreateArchive (jar, ("commonMain/default/manifest", "current")); + CreateArchive (apk, ("commonMain/default/manifest", "existing"), ("stale.txt", "stale")); + CreateArchive (jar, ("commonMain/default/manifest", "current")); - var item = new TaskItem ($"{jar}#commonMain/default/manifest"); - item.SetMetadata ("ArchivePath", "commonMain/default/manifest"); - item.SetMetadata ("JavaArchiveEntry", "commonMain/default/manifest"); + var item = new TaskItem ($"{jar}#commonMain/default/manifest"); + item.SetMetadata ("ArchivePath", "commonMain/default/manifest"); + item.SetMetadata ("JavaArchiveEntry", "commonMain/default/manifest"); - var task = new BuildArchive { - BuildEngine = new MockBuildEngine (TestContext.Out), - ApkOutputPath = apk, - FilesToAddToArchive = new ITaskItem [] { item }, - }; + var task = new BuildArchive { + BuildEngine = new MockBuildEngine (TestContext.Out), + ApkOutputPath = apk, + FilesToAddToArchive = new ITaskItem [] { item }, + }; - Assert.IsTrue (task.RunTask (), "task should have succeeded"); + Assert.IsTrue (task.RunTask (), "task should have succeeded"); - using (var archive = ZipArchive.Open (apk, FileMode.Open)) { - archive.AssertEntryContents (apk, "commonMain/default/manifest", "current"); - archive.AssertDoesNotContainEntry (apk, "stale.txt"); - } + using (var archive = ZipArchive.Open (apk, FileMode.Open)) { + archive.AssertEntryContents (apk, "commonMain/default/manifest", "current"); + archive.AssertDoesNotContainEntry (apk, "stale.txt"); } + } - [Test] - public void ExistingJavaArchiveEntriesAreSkippedWhenUpToDate () - { - var apk = Path.Combine (tempDirectory, "app.apk"); - var jar = Path.Combine (tempDirectory, "classes.jar"); + [Test] + public void ExistingJavaArchiveEntriesAreSkippedWhenUpToDate () + { + var apk = Path.Combine (TempDirectory, "app.apk"); + var jar = Path.Combine (TempDirectory, "classes.jar"); - CreateArchive (apk, ("commonMain/default/manifest", "current")); - CreateArchive (jar, ("commonMain/default/manifest", "current")); + CreateArchive (apk, ("commonMain/default/manifest", "current")); + CreateArchive (jar, ("commonMain/default/manifest", "current")); - var item = new TaskItem ($"{jar}#commonMain/default/manifest"); - item.SetMetadata ("ArchivePath", "commonMain/default/manifest"); - item.SetMetadata ("JavaArchiveEntry", "commonMain/default/manifest"); - var messages = new List (); + var item = new TaskItem ($"{jar}#commonMain/default/manifest"); + item.SetMetadata ("ArchivePath", "commonMain/default/manifest"); + item.SetMetadata ("JavaArchiveEntry", "commonMain/default/manifest"); + var messages = new List (); - var task = new BuildArchive { - BuildEngine = new MockBuildEngine (TestContext.Out, messages: messages), - ApkOutputPath = apk, - FilesToAddToArchive = new ITaskItem [] { item }, - }; + var task = new BuildArchive { + BuildEngine = new MockBuildEngine (TestContext.Out, messages: messages), + ApkOutputPath = apk, + FilesToAddToArchive = new ITaskItem [] { item }, + }; - Assert.IsTrue (task.RunTask (), "task should have succeeded"); + Assert.IsTrue (task.RunTask (), "task should have succeeded"); - Assert.That (messages, Has.Some.Property (nameof (BuildMessageEventArgs.Message)).EqualTo ($"Skipping commonMain/default/manifest from {jar} as it is up to date.")); + Assert.That (messages, Has.Some.Property (nameof (BuildMessageEventArgs.Message)).EqualTo ($"Skipping commonMain/default/manifest from {jar} as it is up to date.")); - using (var archive = ZipArchive.Open (apk, FileMode.Open)) { - archive.AssertEntryContents (apk, "commonMain/default/manifest", "current"); - } + using (var archive = ZipArchive.Open (apk, FileMode.Open)) { + archive.AssertEntryContents (apk, "commonMain/default/manifest", "current"); + } + } + + [Test] + public void DuplicateJavaArchiveEntriesKeepFirstCurrentBuildItem () + { + var apk = Path.Combine (TempDirectory, "app.apk"); + var firstJar = Path.Combine (TempDirectory, "first.jar"); + var secondJar = Path.Combine (TempDirectory, "second.jar"); + + CreateArchive (apk, ("stale.txt", "stale")); + CreateArchive (firstJar, ("commonMain/default/manifest", "first")); + CreateArchive (secondJar, ("commonMain/default/manifest", "second")); + + var firstItem = new TaskItem ($"{firstJar}#commonMain/default/manifest"); + firstItem.SetMetadata ("ArchivePath", "commonMain/default/manifest"); + firstItem.SetMetadata ("JavaArchiveEntry", "commonMain/default/manifest"); + var secondItem = new TaskItem ($"{secondJar}#commonMain/default/manifest"); + secondItem.SetMetadata ("ArchivePath", "commonMain/default/manifest"); + secondItem.SetMetadata ("JavaArchiveEntry", "commonMain/default/manifest"); + var messages = new List (); + + var task = new BuildArchive { + BuildEngine = new MockBuildEngine (TestContext.Out, messages: messages), + ApkOutputPath = apk, + FilesToAddToArchive = new ITaskItem [] { firstItem, secondItem }, + }; + + Assert.IsTrue (task.RunTask (), "task should have succeeded"); + + Assert.That (messages, Has.Some.Property (nameof (BuildMessageEventArgs.Message)).EqualTo ("Failed to add jar entry commonMain/default/manifest from second.jar: the same file already exists in the apk")); + + using (var archive = ZipArchive.Open (apk, FileMode.Open)) { + archive.AssertEntryContents (apk, "commonMain/default/manifest", "first"); + archive.AssertDoesNotContainEntry (apk, "stale.txt"); } + } - static void CreateArchive (string path, params (string name, string contents) [] entries) - { - using (var stream = File.Create (path)) - using (var archive = ZipArchive.Create (stream)) { - foreach (var entry in entries) { - archive.AddEntry (entry.name, entry.contents, encoding: Encoding.UTF8); - } + static void CreateArchive (string path, params (string name, string contents) [] entries) + { + using (var stream = File.Create (path)) + using (var archive = ZipArchive.Create (stream)) { + foreach (var entry in entries) { + archive.AddEntry (entry.name, entry.contents, encoding: Encoding.UTF8); } } } From 2e47ed5dd1099eb1efe441a001e60739f4fce4fe Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 2 Jun 2026 13:04:37 +0000 Subject: [PATCH 6/7] Address BuildArchive validation feedback Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com> --- .../Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs index f5d031aae80..a23d679354c 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Text; +using Microsoft.Android.Build.Tasks; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; using NUnit.Framework; @@ -28,7 +29,7 @@ public void Setup () [TearDown] public void TearDown () { - if (tempDirectory != null && Directory.Exists (tempDirectory)) + if (!tempDirectory.IsNullOrEmpty () && Directory.Exists (tempDirectory)) Directory.Delete (tempDirectory, recursive: true); } @@ -97,7 +98,6 @@ public void DuplicateJavaArchiveEntriesKeepFirstCurrentBuildItem () CreateArchive (apk, ("stale.txt", "stale")); CreateArchive (firstJar, ("commonMain/default/manifest", "first")); - CreateArchive (secondJar, ("commonMain/default/manifest", "second")); var firstItem = new TaskItem ($"{firstJar}#commonMain/default/manifest"); firstItem.SetMetadata ("ArchivePath", "commonMain/default/manifest"); From be77cdef83be0f4069f9a94a0c1b09e41a2a1b90 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Jun 2026 09:35:10 +0000 Subject: [PATCH 7/7] Address review: null-check jar.ReadEntry result; create secondJar on disk in duplicate test Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com> --- src/Xamarin.Android.Build.Tasks/Tasks/BuildArchive.cs | 5 +++++ .../Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs | 1 + 2 files changed, 6 insertions(+) diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/BuildArchive.cs b/src/Xamarin.Android.Build.Tasks/Tasks/BuildArchive.cs index 75aae5d7aa4..e4285c89049 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/BuildArchive.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/BuildArchive.cs @@ -170,6 +170,11 @@ public override bool RunTask () using (var jar = ZipArchive.Open (stream)) { var jar_item = jar.ReadEntry (jar_entry_name); + if (jar_item == null) { + Log.LogDebugMessage ("Failed to add jar entry {0} from {1}: entry not found in jar.", jar_entry_name, Path.GetFileName (jar_file_path)); + continue; + } + if (hasApkEntry) { if (apk.GetEntry (apk_path).CRC == jar_item.CRC) { Log.LogDebugMessage ("Skipping {0} from {1} as it is up to date.", jar_entry_name, jar_file_path); diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs index a23d679354c..ffabd6827e1 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/BuildArchiveTests.cs @@ -98,6 +98,7 @@ public void DuplicateJavaArchiveEntriesKeepFirstCurrentBuildItem () CreateArchive (apk, ("stale.txt", "stale")); CreateArchive (firstJar, ("commonMain/default/manifest", "first")); + CreateArchive (secondJar, ("commonMain/default/manifest", "second")); var firstItem = new TaskItem ($"{firstJar}#commonMain/default/manifest"); firstItem.SetMetadata ("ArchivePath", "commonMain/default/manifest");