Open erikpowa opened 5 years ago
Can't repro anymore. Tested at https://github.com/xamarin/xamarin-android/commit/da46500671b82fa7f15209ea2a091581cbf820f4
My test was faulty 🤦 which used foo-Resources
, but still can repro with lower-case foo-resources
.
Notes for the Xamarin.Android team
This issue will by default result in a FileNotFoundException: Could not load file or assembly exception if an app attempts to load a non-satellite assembly that has a name ending with .resources.dll.
I encountered this behavior myself today in a test failure while working on and unrelated PR, so I started writing an automated build test for it before I found this existing issue. In case it might be handy for some point in the future, here's the test:
[Test]
public void AssembliesThatAreNamedLikeSatelliteAssembliesButAreNot ()
{
var path = Path.Combine ("temp", TestName);
var app = new XamarinAndroidApplicationProject {
ProjectName = "App",
Sources = {
new BuildItem.Source ("Class1.cs") {
TextContent = () => "public class Class1 : Library1.resources.Class1 { }"
},
},
IsRelease = true
};
var lib = new DotNetStandard {
ProjectName = "Library1.resources",
Sdk = "Microsoft.NET.Sdk",
TargetFramework = "netstandard2.0",
Sources = {
new BuildItem.Source ("Class1.cs") {
TextContent = () => "namespace Library1.resources { public class Class1 { } }"
}
}
};
app.References.Add (new BuildItem.ProjectReference ($"..\\{lib.ProjectName}\\{lib.ProjectName}.csproj", lib.ProjectName, lib.ProjectGuid));
using (var libBuilder = CreateDllBuilder (Path.Combine (path, lib.ProjectName), cleanupAfterSuccessfulBuild: false))
using (var appBuilder = CreateApkBuilder (Path.Combine (path, app.ProjectName))) {
Assert.IsTrue (libBuilder.Build (lib), "Library build should have succeeded.");
Assert.IsTrue (appBuilder.Build (app), "App build should have succeeded.");
var archive = Path.Combine (Root, appBuilder.ProjectDirectory, app.OutputPath, $"{app.PackageName}.apk");
using (var zip = ZipHelper.OpenZip (archive)) {
Assert.IsTrue (zip.ContainsEntry ("assemblies/Library1.resources.dll"), $"{archive} should contain an assemblies/Library1.resources.dll entry");
}
}
}
Based on a first look at the underlying problem, it seems the list of satellite assemblies is not preserved separately all the way into the BuildApk
task, so the BuildApk
task currently assumes that any assembly name that matches a certain regular expression should be treated as a satellite assembly:
short: "user" assembly ->
foo-resources.dll
assembly location in apk ->\assemblies\assets\foo-resources.dll
Steps to Reproduce
<AssemblyName>foo-resources</AssemblyName>
Expected Behavior
\assemblies\foo-resources.dll
Actual Behavior
\assemblies\assets\foo-resources.dll
Version Information
master branch
Log File