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

[net6] Building an application can sometimes cause Xamarin.Android.Tasks.TypeMapGenerator.GenerateRelease to fail #7302

Closed
jeromelaban opened this issue Aug 23, 2022 · 9 comments · Fixed by #7340
Assignees
Labels
Area: App+Library Build Issues when building Library projects or Application projects. needs-triage Issues that need to be assigned.

Comments

@jeromelaban
Copy link

jeromelaban commented Aug 23, 2022

Android application type

Android for .NET (net6.0-android, etc.)

Affected platform version

17.3.0

Description

Building an app can sometimes cause this:

C:\Program Files\dotnet\packs\Microsoft.Android.Sdk.Windows\32.0.451\tools\Xamarin.Android.Common.targets(1438,3): error XAGJS7004: System.ArgumentException: An item with the same key has already been added.
   at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at Xamarin.Android.Tasks.TypeMapGenerator.GenerateRelease(Boolean skipJniAddNativeMethodRegistrationAttributeScan, List`1 javaTypes, String outputDirectory, ApplicationConfigTaskState appConfState)
   at Xamarin.Android.Tasks.GenerateJavaStubs.WriteTypeMappings(List`1 types, TypeDefinitionCache cache)
   at Xamarin.Android.Tasks.GenerateJavaStubs.Run(DirectoryAssemblyResolver res)
   at Xamarin.Android.Tasks.GenerateJavaStubs.RunTask()
   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

Steps to Reproduce

  1. Build an app
  2. ? (maybe have a build failure of some kind)
  3. Rebuild, see the failure above.
  4. Clean bin/obj
  5. Rebuild, the build will succeed.

Did you find any workaround?

Cleaning bin/obj folders.

Relevant log output

android-build-failure.zip

@jeromelaban jeromelaban added Area: App+Library Build Issues when building Library projects or Application projects. needs-triage Issues that need to be assigned. labels Aug 23, 2022
@grendello
Copy link
Contributor

This is most likely fixed by dotnet/runtime#67660, would you be able to test your application with a NET7 preview build of Xamarin.Android?

@jeromelaban
Copy link
Author

I could do that. I was under the impression that net7 builds were not ready to be used, but is there a guide to do this kind of testing?

@grendello
Copy link
Contributor

@jonathanpeppers
Copy link
Member

jonathanpeppers commented Sep 1, 2022

@jeromelaban if you are hitting this in .NET 6 with the .NET 6 SDK, can you give some more details about the project you got this error? (I think the .binlog is from VS, and doesn't have the .csproj in it) Do you know if a specific NuGet package causes it?

I think you would hit this with Release builds only.

@jonathanpeppers
Copy link
Member

I can reproduce this when building a .NET 6 MAUI app with a .NET 7 SDK, it appears to be hitting this line:

https://github.com/xamarin/xamarin-android/blob/863cfc540e97134ad6a8875eae31007ec39889ce/src/Xamarin.Android.Build.Tasks/Utilities/TypeMapGenerator.cs#L395

https://github.com/xamarin/xamarin-android/blob/d6224ca6b1032ffebc8fe2b496f93a511b0674a6/src/Xamarin.Android.Build.Tasks/Utilities/TypeMapGenerator.cs#L385

@grendello can we just change this collection to a List<T>? Then we should probably also backport this change to .NET 6.

@jeromelaban
Copy link
Author

@jonathanpeppers I don't recall exactly in which context that could happen, but it seems you've found a way to repro it :) Thanks!

grendello added a commit to grendello/xamarin-android that referenced this issue Sep 6, 2022
Fixes: dotnet#7302
Context: dotnet@7117414

When building .NET6 app on .NET7, sometimes the build fails with:

    C:\Program Files\dotnet\packs\Microsoft.Android.Sdk.Windows\32.0.451\tools\Xamarin.Android.Common.targets(1438,3): error XAGJS7004: System.ArgumentException: An item with the same key has already been added.
     at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
     at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
     at Xamarin.Android.Tasks.TypeMapGenerator.GenerateRelease(Boolean skipJniAddNativeMethodRegistrationAttributeScan, List`1 javaTypes, String outputDirectory, ApplicationConfigTaskState appConfState)
     at Xamarin.Android.Tasks.GenerateJavaStubs.WriteTypeMappings(List`1 types, TypeDefinitionCache cache)
     at Xamarin.Android.Tasks.GenerateJavaStubs.Run(DirectoryAssemblyResolver res)
     at Xamarin.Android.Tasks.GenerateJavaStubs.RunTask()
     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

Avoid that by switching the data structure to `List<T>`, since we no
longer use the Dictionary key for anything.
jonathanpeppers pushed a commit that referenced this issue Sep 6, 2022
Fixes: #7302
Context: 7117414

When building .NET6 app on .NET7, sometimes the build fails with:

    C:\Program Files\dotnet\packs\Microsoft.Android.Sdk.Windows\32.0.451\tools\Xamarin.Android.Common.targets(1438,3): error XAGJS7004: System.ArgumentException: An item with the same key has already been added.
     at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
     at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
     at Xamarin.Android.Tasks.TypeMapGenerator.GenerateRelease(Boolean skipJniAddNativeMethodRegistrationAttributeScan, List`1 javaTypes, String outputDirectory, ApplicationConfigTaskState appConfState)
     at Xamarin.Android.Tasks.GenerateJavaStubs.WriteTypeMappings(List`1 types, TypeDefinitionCache cache)
     at Xamarin.Android.Tasks.GenerateJavaStubs.Run(DirectoryAssemblyResolver res)
     at Xamarin.Android.Tasks.GenerateJavaStubs.RunTask()
     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

Avoid that by switching the data structure to `List<T>`, since we no
longer use the Dictionary key for anything.
jonathanpeppers pushed a commit to jonathanpeppers/xamarin-android that referenced this issue Sep 6, 2022
…7340)

Fixes: dotnet#7302
Context: dotnet@7117414

When building .NET6 app on .NET7, sometimes the build fails with:

    C:\Program Files\dotnet\packs\Microsoft.Android.Sdk.Windows\32.0.451\tools\Xamarin.Android.Common.targets(1438,3): error XAGJS7004: System.ArgumentException: An item with the same key has already been added.
     at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
     at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
     at Xamarin.Android.Tasks.TypeMapGenerator.GenerateRelease(Boolean skipJniAddNativeMethodRegistrationAttributeScan, List`1 javaTypes, String outputDirectory, ApplicationConfigTaskState appConfState)
     at Xamarin.Android.Tasks.GenerateJavaStubs.WriteTypeMappings(List`1 types, TypeDefinitionCache cache)
     at Xamarin.Android.Tasks.GenerateJavaStubs.Run(DirectoryAssemblyResolver res)
     at Xamarin.Android.Tasks.GenerateJavaStubs.RunTask()
     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

Avoid that by switching the data structure to `List<T>`, since we no
longer use the Dictionary key for anything.
jonathanpeppers added a commit that referenced this issue Sep 7, 2022
Fixes: #7302
Context: 7117414

When building .NET6 app on .NET7, sometimes the build fails with:

    C:\Program Files\dotnet\packs\Microsoft.Android.Sdk.Windows\32.0.451\tools\Xamarin.Android.Common.targets(1438,3): error XAGJS7004: System.ArgumentException: An item with the same key has already been added.
     at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
     at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
     at Xamarin.Android.Tasks.TypeMapGenerator.GenerateRelease(Boolean skipJniAddNativeMethodRegistrationAttributeScan, List`1 javaTypes, String outputDirectory, ApplicationConfigTaskState appConfState)
     at Xamarin.Android.Tasks.GenerateJavaStubs.WriteTypeMappings(List`1 types, TypeDefinitionCache cache)
     at Xamarin.Android.Tasks.GenerateJavaStubs.Run(DirectoryAssemblyResolver res)
     at Xamarin.Android.Tasks.GenerateJavaStubs.RunTask()
     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

Avoid that by switching the data structure to `List<T>`, since we no
longer use the Dictionary key for anything.

Co-authored-by: Marek Habersack <grendel@twistedcode.net>
@jonathanpeppers
Copy link
Member

jonathanpeppers commented Sep 7, 2022

So the fix is definitely better, but we hit ~606 XA4215 errors now, such as:

error XA4215: The Java type `androidx.activity.contextaware.OnContextAvailableListener` is generated by more than one managed type. Please change the [Register] attribute so that the same Java type is not emitted.

Likely due to having multiple Xamarin.AndroidX.Activity.dll when building a net6.0-android MAUI app with .NET 7:

obj\Release\net6.0-android\android-arm\linked\Xamarin.AndroidX.Activity.dll
obj\Release\net6.0-android\android-arm64\linked\Xamarin.AndroidX.Activity.dll
obj\Release\net6.0-android\android-x86\linked\Xamarin.AndroidX.Activity.dll
obj\Release\net6.0-android\android-x64\linked\Xamarin.AndroidX.Activity.dll

Normally, these would be reduced to a single assembly.

jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this issue Sep 9, 2022
Fixes: dotnet#7302
Context: dotnet/linker#2203
Context: dotnet/runtime#67660
Context: dotnet#6598

This partially backports 745214d.

In addition to this backport to dotnet/runtime/release/6.0:

dotnet/runtime#75311

We also have another change in .NET 7 that opts into
`$(TrimmerRemoveSymbols)` by default for `Release` builds. This allows
the .NET 7 linker to have stable MVIDs for assemblies for each
architecture.

There may potentially be a dotnet/linker issue here to look into
further. However, this seems to be the best fix for getting .NET 6
projects building under .NET 7 at the moment.
@jonathanpeppers
Copy link
Member

@jeromelaban we've been working on this issue a bit more. I think #7365 solves the underlying issue. (although we might also need dotnet/runtime#75311)

If you set TrimmerRemoveSymbols=true in your project, does it work around the problem?

jonathanpeppers added a commit that referenced this issue Sep 9, 2022
Fixes: #7302
Context: dotnet/linker#2203
Context: dotnet/runtime#67660
Context: #6598

This partially backports 745214d.

Building a `net6.0-android` app in `Release` mode with .NET 7 can fail with many errors like:

    error XA4215: The Java type `androidx.activity.contextaware.OnContextAvailableListener` is generated by more than one managed type. Please change the [Register] attribute so that the same Java type is not emitted.

This happens because we end up with multiple assemblies, such as:

    obj/Release/net6.0-android/android-arm/linked/Xamarin.AndroidX.Activity.dll
    obj/Release/net6.0-android/android-arm64/linked/Xamarin.AndroidX.Activity.dll
    obj/Release/net6.0-android/android-x64/linked/Xamarin.AndroidX.Activity.dll
    obj/Release/net6.0-android/android-x86/linked/Xamarin.AndroidX.Activity.dll

To fix this, in addition to this backport to dotnet/runtime/release/6.0:

dotnet/runtime#75311

In .NET 7 we opt into `$(TrimmerRemoveSymbols)` by default for `Release`
builds. This allows the .NET 7 linker to have stable MVIDs for assemblies
for each architecture. Somehow when the linker outputs `.pdb` files,
it creates different MVIDs per architecture.

There may potentially be a dotnet/linker issue here to look into
further. However, this seems to be the best fix for getting .NET 6
projects building under .NET 7 at the moment.
@jeromelaban
Copy link
Author

jeromelaban commented Sep 15, 2022

@jonathanpeppers I have not seen that issue again recently, knowing the workaround of rebuilding but I'll be on the lookout and try your workaround.

@ghost ghost locked as resolved and limited conversation to collaborators Oct 16, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Area: App+Library Build Issues when building Library projects or Application projects. needs-triage Issues that need to be assigned.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants