Skip to content
New issue

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

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

Already on GitHub? # to your account

Build of MAUI app fails if NuGet package contains references #11364

Closed
AntonKosenkoDX opened this issue Nov 15, 2022 · 17 comments
Closed

Build of MAUI app fails if NuGet package contains references #11364

AntonKosenkoDX opened this issue Nov 15, 2022 · 17 comments
Labels
partner Issue or Request from a partner team platform/android 🤖 s/needs-attention Issue has more information and needs another look t/bug Something isn't working
Milestone

Comments

@AntonKosenkoDX
Copy link

Description

We want to hide our private libraries from IntelliSense for our customers. We followed the instructions from the following guide: Multiple assemblies in one package. This solution works in pure net7.0 apps, but leads to build errors on MAUI apps.

Steps to Reproduce

I prepared a sample repo to demonstrate this issue: https://github.com/AntonKosenkoDX/nuget-refs.

To build this project, please run the build script or execute the following commands:

dotnet build MyUtilities/MyUtilities.csproj
dotnet build MyLib/MyLib.csproj
nuget pack MyNuget/MyNuget.nuspec -OutputDirectory MyNuget/

dotnet build MyApp/MyApp.csproj
dotnet build MyConsoleApp/MyConsoleApp.csproj

You will see that the pure NET7 project is built without errors and it's IntelliSense shows only members from MyLib. Members from MyUtilities are not shown. This behavior is expected.

However, an attempt to build MyApp (MAUI application) results with the following error:

 error XAGJS7028: System.IO.FileNotFoundException: Could not load assembly 'MyUtilities, Version=1.0.0.0, Culture=neutral, PublicKeyToken='. Perhaps it doesn't exist in the Mono for Android profile? 

Link to public reproduction project repository

https://github.com/AntonKosenkoDX/nuget-refs

Version with bug

7.0 (current)

Last version that worked well

Unknown/Other

Affected platforms

Android

Affected platform versions

All

Did you find any workaround?

No

Relevant log output

/usr/local/share/dotnet/packs/Microsoft.Android.Sdk.Darwin/33.0.4/tools/Xamarin.Android.Common.targets(1476,3): error XAGJS7028: System.IO.FileNotFoundException: Could not load assembly 'MyUtilities, Version=1.0.0.0, Culture=neutral, PublicKeyToken='. Perhaps it doesn't exist in the Mono for Android profile? [/Users/antonkosenko/work/nuget-refs/MyApp/MyApp.csproj::TargetFramework=net7.0-android]
/usr/local/share/dotnet/packs/Microsoft.Android.Sdk.Darwin/33.0.4/tools/Xamarin.Android.Common.targets(1476,3): error XAGJS7028: File name: 'MyUtilities.dll' [/Users/antonkosenko/work/nuget-refs/MyApp/MyApp.csproj::TargetFramework=net7.0-android]
/usr/local/share/dotnet/packs/Microsoft.Android.Sdk.Darwin/33.0.4/tools/Xamarin.Android.Common.targets(1476,3): error XAGJS7028:    at Java.Interop.Tools.Cecil.DirectoryAssemblyResolver.Resolve(AssemblyNameReference reference, ReaderParameters parameters) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil/DirectoryAssemblyResolver.cs:line 245 [/Users/antonkosenko/work/nuget-refs/MyApp/MyApp.csproj::TargetFramework=net7.0-android]
/usr/local/share/dotnet/packs/Microsoft.Android.Sdk.Darwin/33.0.4/tools/Xamarin.Android.Common.targets(1476,3): error XAGJS7028:    at Java.Interop.Tools.Cecil.DirectoryAssemblyResolver.Resolve(AssemblyNameReference reference) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil/DirectoryAssemblyResolver.cs:line 191 [/Users/antonkosenko/work/nuget-refs/MyApp/MyApp.csproj::TargetFramework=net7.0-android]
/usr/local/share/dotnet/packs/Microsoft.Android.Sdk.Darwin/33.0.4/tools/Xamarin.Android.Common.targets(1476,3): error XAGJS7028:    at Mono.Cecil.MetadataResolver.Resolve(TypeReference type) in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/cecil/Mono.Cecil/MetadataResolver.cs:line 110 [/Users/antonkosenko/work/nuget-refs/MyApp/MyApp.csproj::TargetFramework=net7.0-android]
/usr/local/share/dotnet/packs/Microsoft.Android.Sdk.Darwin/33.0.4/tools/Xamarin.Android.Common.targets(1476,3): error XAGJS7028:    at Mono.Cecil.ModuleDefinition.Resolve(TypeReference type) in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/cecil/Mono.Cecil/ModuleDefinition.cs:line 762 [/Users/antonkosenko/work/nuget-refs/MyApp/MyApp.csproj::TargetFramework=net7.0-android]
/usr/local/share/dotnet/packs/Microsoft.Android.Sdk.Darwin/33.0.4/tools/Xamarin.Android.Common.targets(1476,3): error XAGJS7028:    at Mono.Cecil.TypeReference.Resolve() in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/cecil/Mono.Cecil/TypeReference.cs:line 278 [/Users/antonkosenko/work/nuget-refs/MyApp/MyApp.csproj::TargetFramework=net7.0-android]
/usr/local/share/dotnet/packs/Microsoft.Android.Sdk.Darwin/33.0.4/tools/Xamarin.Android.Common.targets(1476,3): error XAGJS7028:    at Java.Interop.Tools.Cecil.TypeDefinitionCache.Resolve(TypeReference typeReference) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil/TypeDefinitionCache.cs:line 20 [/Users/antonkosenko/work/nuget-refs/MyApp/MyApp.csproj::TargetFramework=net7.0-android]
/usr/local/share/dotnet/packs/Microsoft.Android.Sdk.Darwin/33.0.4/tools/Xamarin.Android.Common.targets(1476,3): error XAGJS7028:    at Java.Interop.Tools.Cecil.TypeDefinitionRocks.GetBaseType(TypeDefinition type, IMetadataResolver resolver) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil/TypeDefinitionRocks.cs:line 23 [/Users/antonkosenko/work/nuget-refs/MyApp/MyApp.csproj::TargetFramework=net7.0-android]
/usr/local/share/dotnet/packs/Microsoft.Android.Sdk.Darwin/33.0.4/tools/Xamarin.Android.Common.targets(1476,3): error XAGJS7028:    at Java.Interop.Tools.Cecil.TypeDefinitionRocks.GetTypeAndBaseTypes(TypeDefinition type, IMetadataResolver resolver)+MoveNext() in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil/TypeDefinitionRocks.cs:line 40 [/Users/antonkosenko/work/nuget-refs/MyApp/MyApp.csproj::TargetFramework=net7.0-android]
/usr/local/share/dotnet/packs/Microsoft.Android.Sdk.Darwin/33.0.4/tools/Xamarin.Android.Common.targets(1476,3): error XAGJS7028:    at Java.Interop.Tools.Cecil.TypeDefinitionRocks.IsSubclassOf(TypeDefinition type, String typeName, IMetadataResolver resolver) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil/TypeDefinitionRocks.cs:line 94 [/Users/antonkosenko/work/nuget-refs/MyApp/MyApp.csproj::TargetFramework=net7.0-android]
/usr/local/share/dotnet/packs/Microsoft.Android.Sdk.Darwin/33.0.4/tools/Xamarin.Android.Common.targets(1476,3): error XAGJS7028:    at Java.Interop.Tools.JavaCallableWrappers.JavaTypeScanner.AddJavaTypes(List`1 javaTypes, TypeDefinition type) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers/JavaTypeScanner.cs:line 58 [/Users/antonkosenko/work/nuget-refs/MyApp/MyApp.csproj::TargetFramework=net7.0-android]
/usr/local/share/dotnet/packs/Microsoft.Android.Sdk.Darwin/33.0.4/tools/Xamarin.Android.Common.targets(1476,3): error XAGJS7028:    at Java.Interop.Tools.JavaCallableWrappers.JavaTypeScanner.GetJavaTypes(IEnumerable`1 assemblies, IAssemblyResolver resolver) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers/JavaTypeScanner.cs:line 48 [/Users/antonkosenko/work/nuget-refs/MyApp/MyApp.csproj::TargetFramework=net7.0-android]
/usr/local/share/dotnet/packs/Microsoft.Android.Sdk.Darwin/33.0.4/tools/Xamarin.Android.Common.targets(1476,3): error XAGJS7028:    at Xamarin.Android.Tasks.GenerateJavaStubs.Run(DirectoryAssemblyResolver res) [/Users/antonkosenko/work/nuget-refs/MyApp/MyApp.csproj::TargetFramework=net7.0-android]
/usr/local/share/dotnet/packs/Microsoft.Android.Sdk.Darwin/33.0.4/tools/Xamarin.Android.Common.targets(1476,3): error XAGJS7028:    at Xamarin.Android.Tasks.GenerateJavaStubs.RunTask() [/Users/antonkosenko/work/nuget-refs/MyApp/MyApp.csproj::TargetFramework=net7.0-android]
/usr/local/share/dotnet/packs/Microsoft.Android.Sdk.Darwin/33.0.4/tools/Xamarin.Android.Common.targets(1476,3): error XAGJS7028:    at Microsoft.Android.Build.Tasks.AndroidTask.Execute() in /Users/runner/work/1/s/xamarin-android/external/xamarin-android-tools/src/Microsoft.Android.Build.BaseTasks/AndroidTask.cs:line 17 [/Users/antonkosenko/work/nuget-refs/MyApp/MyApp.csproj::TargetFramework=net7.0-android]
@AntonKosenkoDX AntonKosenkoDX added the t/bug Something isn't working label Nov 15, 2022
@jsuarezruiz jsuarezruiz added the partner Issue or Request from a partner team label Nov 15, 2022
@jsuarezruiz
Copy link
Contributor

cc @jonathanpeppers

@ghost
Copy link

ghost commented Nov 15, 2022

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

@jonathanpeppers
Copy link
Member

Can you share the .nupkg files you created in the example above? (Or at least just list the file contents)

Also an MSBuild diagnostic log would help us look into the error message. Thanks!

@jonathanpeppers jonathanpeppers added the s/needs-info Issue needs more info from the author label Nov 15, 2022
@ghost
Copy link

ghost commented Nov 15, 2022

Hi @AntonKosenkoDX. We have added the "s/needs-info" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

@AntonKosenkoDX
Copy link
Author

Hello @jonathanpeppers! Thanks for fast response.
I've added .nupkg file here:
https://github.com/AntonKosenkoDX/nuget-refs/tree/main/MyNuget
And diagnostic log here:
https://github.com/AntonKosenkoDX/nuget-refs/blob/main/MyApp/msbuild-diagnostic.log

Hope it helps.

@ghost ghost added s/needs-attention Issue has more information and needs another look and removed s/needs-info Issue needs more info from the author labels Nov 15, 2022
@jonathanpeppers
Copy link
Member

jonathanpeppers commented Nov 15, 2022

Hmm, how did you end up with:

image

Does the problem go away with TargetFramework=net7.0-android33??? That should actually be the default value, but 31 is in your package.

@AntonKosenkoDX
Copy link
Author

AntonKosenkoDX commented Nov 16, 2022

I've just tried to up target version to android33 and the error still appears(
And.. Are you able to reproduce this issue on your side? I'm getting the error pretty stable with the sample that I prepared - https://github.com/AntonKosenkoDX/nuget-refs.

@AntonKosenkoDX
Copy link
Author

@jonathanpeppers ?

@jonathanpeppers
Copy link
Member

@AntonKosenkoDX your .nuspec file has:

<group targetFramework="net7.0-android31.0"/>

There are also manual file paths like:

<file src=".\..\MyLib\bin\Debug\net7.0-android\MyLib.dll" target="ref\net7.0-android31.0"/>
<file src=".\..\MyLib\bin\Debug\net7.0-android\MyLib.dll" target="lib\net7.0-android31.0"/>
<file src=".\..\MyUtilities\bin\Debug\net7.0-android\MyUtilities.dll" target="lib\net7.0-android31.0"/>
<file src=".\..\MyLib\bin\Debug\net7.0-android\MyLib.aar" target="lib\net7.0-android31.0"/>
<file src=".\..\MyUtilities\bin\Debug\net7.0-android\MyUtilities.aar" target="lib\net7.0-android31.0"/>

If you change these all to 33, does it solve the issue?

@jonathanpeppers jonathanpeppers added s/needs-info Issue needs more info from the author and removed s/needs-attention Issue has more information and needs another look labels Nov 18, 2022
@ghost
Copy link

ghost commented Nov 18, 2022

Hi @AntonKosenkoDX. We have added the "s/needs-info" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

@AntonKosenkoDX
Copy link
Author

@jonathanpeppers As I said before I updated android version to 33 in my .nuspec but it didn't fix the problem. I've also double checked this just now and have updated the reproducing sample.
https://github.com/AntonKosenkoDX/nuget-refs/blob/main/MyNuget/MyNuget.nuspec

@ghost ghost added s/needs-attention Issue has more information and needs another look and removed s/needs-info Issue needs more info from the author labels Nov 19, 2022
@jonathanpeppers
Copy link
Member

I can try it again on Monday, it looks like you updated the repo above.

AntonKosenkoDX/nuget-refs@0ec315d

@AntonKosenkoDX
Copy link
Author

Ok, thanks!

@jonathanpeppers
Copy link
Member

So it's been a little while since I've used a .nuspec, but I just fixed everything a bit and it works for me.

See: AntonKosenkoDX/nuget-refs#1

Notes:

  • Use dotnet pack instead of .nuspec -- it might be easier? I would just pack the top level assembly and add extra files as needed.
  • If you use a ref folder actually put reference assemblies in there. (see docs)
  • When I did a build, there was no reference added to MyUtility.dll, and it was in fact not in the MSBuild .binlog at all -- I added to the .nuspec to add it
  • If you have a reference assembly, you need to put the .aar file next to it, for that to work.

I suspect some of these details would have gone away with dotnet pack. Hope that helps!

@AntonKosenkoDX
Copy link
Author

@jonathanpeppers thanks for your PR.
But I feel that you're still misunderstanding me. I know that if I add references to .nuspec file, it will work.
As I mentioned in first post, I want to hide API from MyUtilities.dll in end-user apps. I use way described in this guide Multiple assemblies in one package - and it works perfectly for pure net7.0 apps (and even for net7.0-ios) but leads to compilation errors in net7.0-android.

Here is a desired behavior:
image

Here is actual (with your PR):
image

@jonathanpeppers
Copy link
Member

Can you mark the types internal? And use InternalsVisibleTo?

I don't think it works for the console app either... If you dotnet publish --self-contained -r win-x64, for example, you don't end up with MyUtilities.dll in MyConsoleApp\bin\Debug\net7.0\win-x64\publish.

We're basically seeing the same behavior on Android, except an MSBuild task fails. With the console app it would crash at runtime in a self-contained app.

jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Dec 15, 2022
Fixes: dotnet/maui#10154

If you have a solution setup with:

* `ApplicationA` project reference ->
* `LibraryB` reference ->
* `LibraryC`

The app will crash at runtime, due to a missing `LibraryC.dll`.

You can solve the problem by changing `@(Reference)` to a
`@(ProjectReference)`. However, it appears the same situation works in
a .NET 7 self-contained console app:

    dotnet publish --self-contained -r win-x64
    ...
    ls -n .\bin\Debug\net7.0\win-x64\publish\LibraryC.dll
    LibraryC.dll

The underlying issue appears to be:

https://github.com/dotnet/msbuild/blob/a2490dd3f78cce4abc8f9e6f1b5268437332818f/src/Tasks/Microsoft.Common.CurrentVersion.targets#L2322

In the console app, `$(BuildingProject)` is `true` and
`$(_FindDependencies)` is empty.

In the android app, `$(BuildingProject)` is `false` and
`$(_FindDependencies)` is `false`.

It appears the `BuildOnlySettings` target *should* be running in
Android apps when we do an "inner" build per `$(RuntimeIdentifier)`.
Simply adding a dependency for the `_ComputeFilesToPublishForRuntimeIdentifiers`
MSBuild target solves this issue.

This likely might fix other issues, such as:

dotnet/maui#11364

I added a test for this scenario.
@jonathanpeppers
Copy link
Member

There might be an underlying issue here, such as:

dotnet/android#7642

@AntonKosenkoDX if you put this in your main app .csproj, does it workaround the issue?

<PropertyGroup>
  <_ResolveReferenceDependencies>true</_ResolveReferenceDependencies>
</PropertyGroup>

jonpryor pushed a commit to dotnet/android that referenced this issue Jan 4, 2023
)

Fixes: dotnet/maui#10154

Context? dotnet/maui#11364

If you have a solution setup with:

  * `ApplicationA.csproj` has a `@(ProjectReference)` to
    `LibraryB.csproj`.
  * `LibraryB.csproj` which has a `@(Reference)` to `LibraryC.dll`,
    built by-
  * `LibraryC.csproj`

The app will crash at runtime, due to a missing `LibraryC.dll`.

The workaround is for `LibraryB.csproj` to use `@(ProjectReference)`
to `LibraryC.csproj` instead of `@(Reference)` to `LibraryC.dll`.

However, it appears the same situation works in a .NET 7
self-contained console app:

	% dotnet publish --self-contained -r win-x64
	…
	% ls -1 .\bin\Debug\net7.0\win-x64\publish\LibraryC.dll
	LibraryC.dll

The underlying issue appears to be due to [`$(_FindDependencies)`][0]:

	<_FindDependencies Condition="'$(BuildingProject)' != 'true' and '$(_ResolveReferenceDependencies)' != 'true'">false</_FindDependencies>

In the console app, `$(BuildingProject)`=true and
`$(_FindDependencies)` is empty.

In the Android app, `$(BuildingProject)`=false and
`$(_FindDependencies)` is `false`.

It appears that the `BuildOnlySettings` target *should* be running in
Android apps when we do an "inner" build per `$(RuntimeIdentifier)`.
Simply updating `_ComputeFilesToPublishForRuntimeIdentifiers` so that
the `BuildOnlySettings` target is in `DependsOnTargets` fixes this.
However, this also causes satellite assemblies to now be automatically
found by the .NET SDK.  Update `@(_AndroidResolvedSatellitePaths)` so
that `@(ReferenceSatellitePaths)` is only included on Classic builds,
preventing duplicate entries.

[0]: https://github.com/dotnet/msbuild/blob/a2490dd3f78cce4abc8f9e6f1b5268437332818f/src/Tasks/Microsoft.Common.CurrentVersion.targets#L2322
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Jan 5, 2023
…tnet#7642)

Fixes: dotnet/maui#10154

Context? dotnet/maui#11364

If you have a solution setup with:

  * `ApplicationA.csproj` has a `@(ProjectReference)` to
    `LibraryB.csproj`.
  * `LibraryB.csproj` which has a `@(Reference)` to `LibraryC.dll`,
    built by-
  * `LibraryC.csproj`

The app will crash at runtime, due to a missing `LibraryC.dll`.

The workaround is for `LibraryB.csproj` to use `@(ProjectReference)`
to `LibraryC.csproj` instead of `@(Reference)` to `LibraryC.dll`.

However, it appears the same situation works in a .NET 7
self-contained console app:

	% dotnet publish --self-contained -r win-x64
	…
	% ls -1 .\bin\Debug\net7.0\win-x64\publish\LibraryC.dll
	LibraryC.dll

The underlying issue appears to be due to [`$(_FindDependencies)`][0]:

	<_FindDependencies Condition="'$(BuildingProject)' != 'true' and '$(_ResolveReferenceDependencies)' != 'true'">false</_FindDependencies>

In the console app, `$(BuildingProject)`=true and
`$(_FindDependencies)` is empty.

In the Android app, `$(BuildingProject)`=false and
`$(_FindDependencies)` is `false`.

It appears that the `BuildOnlySettings` target *should* be running in
Android apps when we do an "inner" build per `$(RuntimeIdentifier)`.
Simply updating `_ComputeFilesToPublishForRuntimeIdentifiers` so that
the `BuildOnlySettings` target is in `DependsOnTargets` fixes this.
However, this also causes satellite assemblies to now be automatically
found by the .NET SDK.  Update `@(_AndroidResolvedSatellitePaths)` so
that `@(ReferenceSatellitePaths)` is only included on Classic builds,
preventing duplicate entries.

[0]: https://github.com/dotnet/msbuild/blob/a2490dd3f78cce4abc8f9e6f1b5268437332818f/src/Tasks/Microsoft.Common.CurrentVersion.targets#L2322
@ghost ghost locked as resolved and limited conversation to collaborators Jan 14, 2023
# for free to subscribe to this conversation on GitHub. Already have an account? #.
Labels
partner Issue or Request from a partner team platform/android 🤖 s/needs-attention Issue has more information and needs another look t/bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants