Skip to content

Commit 21d98c1

Browse files
committed
[Xamarin.Android.Build.Tasks] Wrong AndroidManifest.xml packaged to the APK while using binding library
Fixes #4804 We were overwriting the AndroidManifest.xml file in the apk with ones from Support Libraries. This manifests itself with the following error ``` Failed to parse APK info: failed to parse AndroidManifest.xml, error: %!s() deploy failed, error: failed to get apk infos, output: W/ResourceType( 5266): Bad XML block: ``` This commit fixes this issue by ignoring files from .jar files which already exist in the apk. This stops things from being overwritten. A test has also been added.
1 parent 77464dc commit 21d98c1

File tree

4 files changed

+76
-7
lines changed

4 files changed

+76
-7
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#### Wrong AndroidManifest.xml packaged to the APK while using binding library
2+
3+
* [GitHub 4812][0]: We were overwriting the AndroidManifest.xml file
4+
in the apk with ones from Support Libraries. This manifests itself
5+
with the following error
6+
7+
```
8+
Failed to parse APK info: failed to parse AndroidManifest.xml, error: %!s()
9+
deploy failed, error: failed to get apk infos, output: W/ResourceType( 5266): Bad XML block:
10+
```
11+
12+
13+
[0]: https://github.com/xamarin/xamarin-android/pull/4812

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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public class BuildApk : AndroidTask
2828

2929
[Required]
3030
public string ApkInputPath { get; set; }
31-
31+
3232
[Required]
3333
public string ApkOutputPath { get; set; }
3434

@@ -101,7 +101,7 @@ bool _Debug {
101101
}
102102

103103
SequencePointsMode sequencePointsMode = SequencePointsMode.None;
104-
104+
105105
public ITaskItem[] LibraryProjectJars { get; set; }
106106
string [] uncompressedFileExtensions;
107107

@@ -241,6 +241,10 @@ void ExecuteWithAbi (string [] supportedAbis, string apkInputPath, string apkOut
241241
Log.LogDebugMessage ($"Skipping {path} as the archive file is up to date.");
242242
continue;
243243
}
244+
if (apk.Archive.Any (e => e.FullName == path)) {
245+
Log.LogMessage ("Warning: failed to add jar entry {0} from {1}: the same file already exists in the apk", name, Path.GetFileName (jarFile));
246+
continue;
247+
}
244248
byte [] data;
245249
using (var d = new MemoryStream ()) {
246250
jarItem.Extract (d);
@@ -256,7 +260,7 @@ void ExecuteWithAbi (string [] supportedAbis, string apkInputPath, string apkOut
256260
count = 0;
257261
}
258262
}
259-
// Clean up Removed files.
263+
// Clean up Removed files.
260264
foreach (var entry in existingEntries) {
261265
Log.LogDebugMessage ($"Removing {entry} as it is not longer required.");
262266
apk.Archive.DeleteEntry (entry);
@@ -296,7 +300,7 @@ public override bool RunTask ()
296300
var apk = Path.GetFileNameWithoutExtension (ApkOutputPath);
297301
ExecuteWithAbi (new [] { abi }, String.Format ("{0}-{1}", ApkInputPath, abi),
298302
Path.Combine (path, String.Format ("{0}-{1}.apk", apk, abi)),
299-
debug, compress, compressedAssembliesInfo);
303+
debug, compress, compressedAssembliesInfo);
300304
outputFiles.Add (Path.Combine (path, String.Format ("{0}-{1}.apk", apk, abi)));
301305
}
302306
}
@@ -548,7 +552,7 @@ string GetNativeLibraryAbi (ITaskItem lib)
548552
{
549553
// If Abi is explicitly specified, simply return it.
550554
var lib_abi = MonoAndroidHelper.GetNativeLibraryAbi (lib);
551-
555+
552556
if (string.IsNullOrWhiteSpace (lib_abi)) {
553557
Log.LogCodedError ("XA4301", lib.ItemSpec, 0, Properties.Resources.XA4301_ABI, lib.ItemSpec);
554558
return null;

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

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,7 @@ public void CheckTheCorrectRuntimeAssemblyIsUsedFromNuget ()
672672
ns.SetProperty ("Description", "Test");
673673
ns.SetProperty ("PackageOutputPath", path);
674674

675-
675+
676676
var xa = new XamarinAndroidApplicationProject () {
677677
ProjectName = "App",
678678
PackageReferences = {
@@ -789,5 +789,53 @@ public void MissingSatelliteAssemblyInApp ()
789789
}
790790
}
791791
}
792+
793+
[Test]
794+
public void IgnoreManifestFromJar ()
795+
{
796+
string java = @"
797+
package com.xamarin.testing;
798+
799+
public class Test
800+
{
801+
}
802+
";
803+
var path = Path.Combine (Root, "temp", TestName);
804+
var javaDir = Path.Combine (path, "java", "com", "xamarin", "testing");
805+
if (Directory.Exists (javaDir))
806+
Directory.Delete (javaDir, true);
807+
Directory.CreateDirectory (javaDir);
808+
File.WriteAllText (Path.Combine (javaDir, "..", "..", "..", "AndroidManifest.xml"), @"<?xml version='1.0' ?><maniest />");
809+
var lib = new XamarinAndroidBindingProject () {
810+
AndroidClassParser = "class-parse",
811+
ProjectName = "Binding1",
812+
};
813+
lib.MetadataXml = "<metadata></metadata>";
814+
lib.Jars.Add (new AndroidItem.EmbeddedJar (Path.Combine ("java", "test.jar")) {
815+
BinaryContent = new JarContentBuilder () {
816+
BaseDirectory = Path.Combine (path, "java"),
817+
JarFileName = "test.jar",
818+
JavaSourceFileName = Path.Combine ("com", "xamarin", "testing", "Test.java"),
819+
JavaSourceText = java,
820+
AdditionalFileExtensions = "*.xml",
821+
}.Build
822+
});
823+
var app = new XamarinAndroidApplicationProject {
824+
IsRelease = true,
825+
};
826+
app.References.Add (new BuildItem.ProjectReference ($"..\\{lib.ProjectName}\\{lib.ProjectName}.csproj", lib.ProjectName, lib.ProjectGuid));
827+
828+
using (var builder = CreateDllBuilder (Path.Combine (path, lib.ProjectName))) {
829+
Assert.IsTrue (builder.Build (lib), "Build of jar should have succeeded.");
830+
using (var zip = ZipHelper.OpenZip (Path.Combine (path, "java", "test.jar"))) {
831+
Assert.IsTrue (zip.ContainsEntry ($"AndroidManifest.xml"), "Jar should contain AndroidManifest.xml");
832+
}
833+
using (var b = CreateApkBuilder (Path.Combine (path, app.ProjectName))) {
834+
Assert.IsTrue (b.Build (app), "Build of jar should have succeeded.");
835+
string expected = "failed to add jar entry AndroidManifest.xml from test.jar: the same file already exists in the apk";
836+
Assert.IsTrue (b.LastBuildOutput.ContainsText (expected), $"AndroidManifest.xml for test.jar should have been ignored.");
837+
}
838+
}
839+
}
792840
}
793841
}

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/JarContentBuilder.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ public class JarContentBuilder : ContentBuilder
1616
public string JavaSourceFileName { get; set; }
1717
public string JavaSourceText { get; set; }
1818

19+
public string AdditionalFileExtensions { get; set; }
20+
1921
public JarContentBuilder ()
2022
{
2123
Action<TraceLevel, string> logger = (level, value) => {
@@ -57,9 +59,11 @@ public override byte [] Build ()
5759
File.Delete (jarfile);
5860
var args = new string [] { "cvf", JarFileName };
5961
var classes = Directory.GetFiles (Path.GetDirectoryName (src), "*.class", SearchOption.AllDirectories);
62+
var additionalFiles = Directory.GetFiles (Path.GetDirectoryName (BaseDirectory), AdditionalFileExtensions, SearchOption.AllDirectories);
63+
var files = classes.Concat (additionalFiles);
6064
var jarPsi = new ProcessStartInfo () {
6165
FileName = JarFullPath,
62-
Arguments = string.Join (" ", args.Concat (classes.Select (c => c.Substring (BaseDirectory.Length + 1)).ToArray ())),
66+
Arguments = string.Join (" ", args.Concat (files.Select (c => c.Substring (BaseDirectory.Length + 1)).ToArray ())),
6367
WorkingDirectory = BaseDirectory,
6468
UseShellExecute = false,
6569
RedirectStandardOutput = true,

0 commit comments

Comments
 (0)