Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assembly ending with "resources" causing mislocated assembly in apk #3745

Open
erikpowa opened this issue Oct 7, 2019 · 3 comments
Open
Assignees

Comments

@erikpowa
Copy link
Contributor

erikpowa commented Oct 7, 2019

short:
"user" assembly -> foo-resources.dll
assembly location in apk -> \assemblies\assets\foo-resources.dll

Steps to Reproduce

  1. Create empty app
  2. Create a library
  3. Add property to library <AssemblyName>foo-resources</AssemblyName>
  4. Reference the library
  5. BuildApk

Expected Behavior

\assemblies\foo-resources.dll

Actual Behavior

\assemblies\assets\foo-resources.dll

Version Information

master branch

Log File

@erikpowa
Copy link
Contributor Author

Can't repro anymore. Tested at da46500

@erikpowa
Copy link
Contributor Author

My test was faulty 🤦 which used foo-Resources, but still can repro with lower-case foo-resources.

@erikpowa erikpowa reopened this Oct 24, 2019
@brendanzagaeski
Copy link
Contributor

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:

https://github.com/xamarin/xamarin-android/blob/22bc14b1a89352824d2a54f6e12a4dbeaa6fe679/src/Xamarin.Android.Build.Tasks/Tasks/BuildApk.cs#L499-L501

https://github.com/xamarin/xamarin-android/blob/22bc14b1a89352824d2a54f6e12a4dbeaa6fe679/src/Xamarin.Android.Build.Tasks/Utilities/SatelliteAssembly.cs#L9-L13

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants