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

[Android] Throws runtime error in mscorlib, expected class System.Runtime.CompilerServices.ValueTaskAwaiter1 #82193

Closed
sacOO7 opened this issue Feb 14, 2023 · 20 comments · Fixed by #82618
Assignees
Milestone

Comments

@sacOO7
Copy link

sacOO7 commented Feb 14, 2023

Description

I am unable to use ably package with a dependency on System.Threading.Channels (the error might also have origin from System.Threading.Tasks.Extensions/System.Runtime.CompilerServices.Unsafe assembly) , throws below runtime exception on MAUI android.

Throws a runtime error while trying to run on android =>

System.TypeLoadException: 'Could not load type of field 'IO.Ably.Realtime.Workflow.RealtimeWorkflow+d__36:<>u__2' (11) due to:
Could not resolve type with token 010000ba from typeref (expected class 'System.Runtime.CompilerServices.ValueTaskAwaiter1' 
in assembly 'mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e')
assembly:mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e type:System.Runtime.CompilerServices.ValueTaskAwaiter1 member:(null)

It works on a regular net6.0 library, MAUI windows machine, and the latest Xamarin Forms.

I tried all options to disable assembly trimming as per
https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/trimming-options?pivots=dotnet-6-0
but the issue still persists and the app throws an error at runtime.

I strongly feel the issue is related to a missing type in mscorlib same as the one mentioned in dotnet/maui#5078 and dotnet/maui#5142

Steps to Reproduce

  1. Clone the project from https://github.com/sac-fork/MauiAppAblyDemo
  2. Build and run it on android emulater ( I used default Pixel 5 - API 33 (API 13 - API 33) )
  3. Tap on Click me button, it will throw above error.

Link to public reproduction project repository

https://github.com/sac-fork/MauiAppAblyDemo

Version with bug

6.0 / 7.0

Last version that worked well

Unknown/Other

Affected platforms

Android

Affected platform versions

Android API 13 to 33

Did you find any workaround?

No workarounds were found.

Relevant log output

System.TypeLoadException: 'Could not load type of field 'IO.Ably.Realtime.Workflow.RealtimeWorkflow+d__36:<>u__2' (11) due to: Could not resolve type with token 010000ba from typeref (expected class 'System.Runtime.CompilerServices.ValueTaskAwaiter1' in assembly 'mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e') assembly:mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e type:System.Runtime.CompilerServices.ValueTaskAwaiter1 member:(null)
@sacOO7 sacOO7 changed the title Unable to use System.Threading.Channels throws error in mscorlib Unable to use System.Threading.Channels throws runtime error in mscorlib Feb 14, 2023
@sacOO7 sacOO7 changed the title Unable to use System.Threading.Channels throws runtime error in mscorlib Unable to use System.Threading.Channels throws runtime error in mscorlib, expected class System.Runtime.CompilerServices.ValueTaskAwaiter1 Feb 14, 2023
@sacOO7 sacOO7 changed the title Unable to use System.Threading.Channels throws runtime error in mscorlib, expected class System.Runtime.CompilerServices.ValueTaskAwaiter1 Throws runtime error in mscorlib, expected class System.Runtime.CompilerServices.ValueTaskAwaiter1 Feb 14, 2023
@sacOO7 sacOO7 changed the title Throws runtime error in mscorlib, expected class System.Runtime.CompilerServices.ValueTaskAwaiter1 Throws runtime error in mscorlib, expected class System.Runtime.CompilerServices.ValueTaskAwaiter1 Feb 14, 2023
@sacOO7 sacOO7 changed the title Throws runtime error in mscorlib, expected class System.Runtime.CompilerServices.ValueTaskAwaiter1 [Android] Throws runtime error in mscorlib, expected class System.Runtime.CompilerServices.ValueTaskAwaiter1 Feb 14, 2023
@sacOO7
Copy link
Author

sacOO7 commented Feb 14, 2023

@Redth and @XamlTest can we please include fix for this issue as a part of next release?

@Xyncgas
Copy link

Xyncgas commented Feb 14, 2023

I can use System.threading.channel as you said, you should reach out to ably too meanwhile check if trimming is what's breaking this if is then you can also have guys at roslyn or ASP.NET take a look for you

@sacOO7
Copy link
Author

sacOO7 commented Feb 15, 2023

I am the person from ably responsible for maintaining the ably-package. I don't think there is an issue with the ably-package. Can you clone the project https://github.com/sac-fork/MauiAppAblyDemo and try running it on android? Because it works fine on windows machines but doesn't work properly on android. Also, as mentioned in the description #82193, I have tried all options to disable assembly trimming, but no luck : (.
So, issues surely have to do with mscorlib same as dotnet/maui#5078 and dotnet/maui#5142

@dotnet-issue-labeler
Copy link

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@rachelkang rachelkang transferred this issue from dotnet/maui Feb 15, 2023
@ghost ghost added the untriaged New issue has not been triaged by the area owner label Feb 15, 2023
@sacOO7
Copy link
Author

sacOO7 commented Feb 16, 2023

@rachelkang I am not sure why this issue was transferred to dotnet/runtime, but I am skeptical about getting it fixed sooner. ( There are already 8k+ active issues on this repository ) Can you please add this issue to your priority queue ?

@sacOO7
Copy link
Author

sacOO7 commented Feb 21, 2023

Any update on this @Redth and @XamlTest ?

CC @rachelkang

@marek-safar
Copy link
Contributor

The problem is very likely down to this dependency 'System.Runtime.CompilerServices.ValueTaskAwaiter1' in assembly 'mscorlib, Version=2.0.5.0. One of your packages is not targeting .NET5+ but original Xamarin only. This should in theory work but it's always tricky combination.

@steveisok could you check why it's failing?

@sacOO7
Copy link
Author

sacOO7 commented Feb 21, 2023

@marek-safar can you try this app ->https://github.com/sac-fork/MauiAppAblyDemo?

If you have a workaround to get this working, it will be super useful 🥇

@steveisok steveisok removed the untriaged New issue has not been triaged by the area owner label Feb 23, 2023
@steveisok steveisok added this to the 8.0.0 milestone Feb 23, 2023
@akoeplinger
Copy link
Member

akoeplinger commented Feb 23, 2023

@sacOO7 the short answer is that you need to add a net6.0 target to your nuget package to fix the issue.

Long answer:

.NET (Core) provides a compatibility mechanism for using assemblies which were compiled against the legacy .NET Framework assembly layout (e.g. mscorlib.dll, System.dll etc). The way this works is that we ship a tiny shim mscorlib.dll which is only used to forward the types to their new locations in a different assembly on modern .NET (e.g. System.Private.CoreLib.dll).

However this breaks down in this case since the classic Xamarin.Android frameworks used the classic Mono implementation of .NET Framework and we made a few additions that didn't exist in the original Microsoft .NET Framework implementation, mainly to support .NET Standard 2.1 use cases.

Your nuget package contains these target frameworks:
image

The net6.0-android target framework has a compatibility fallback path with monoandroid so the build uses the assembly from that folder instead of e.g. the netstandard2.0, since it is considered more compatible.
However that assembly was compiled against a Xamarin.Android-specific mscorlib.dll which contained types like ValueTaskAwaiter<T> and ReadOnlySpan<T> so the assembly expects them to be there. The compatibility shim mscorlib.dll however doesn't have type forwarders for these types (since they didn't exist on the Microsoft .NET Framework implementation) and we get the TypeLoadException.

A quick way to hack it is to go into your local nuget package cache folder <home directory>/.nuget/packages/ably.io/1.2.10/lib/ and remove the monoandroid folder there, then rebuild the app. That will make it pick the netstandard2.0 version instead which works:

image

But the real solution is to add a proper net6.0 target to your nuget package so that assembly will be picked instead of the monoandroid one.

@sacOO7
Copy link
Author

sacOO7 commented Feb 23, 2023

@akoeplinger Thanks for the answer!

I had one final question.
If target for .Net6 is not yet added, why does it show support for .Net 6/ .Net7 under nuget
https://www.nuget.org/packages/ably.io#supportedframeworks-body-tab ?

@sacOO7
Copy link
Author

sacOO7 commented Feb 23, 2023

Also, I feel the project should throw a proper error/ warning if the .Net 6 or .Net 7 target is not found in the package.

@akoeplinger
Copy link
Member

If target for .Net6 is not yet added, why does it show support for .Net 6/ .Net7 under nuget

See the legend at the bottom of the table, that target is "computed", because we have this compatibility layer so monoandroid or net46 works on modern .NET.

image

We can't throw an error since this is supposed to work, you're just hitting an edge case where it doesn't. The compatibility layer is best effort which is why we're recommending adding a real net6.0 target.

@sacOO7
Copy link
Author

sacOO7 commented Feb 23, 2023

Got it @akoeplinger. I had few small questions coming up.

  1. Can we make project choose netstandard 2.0 assembly instead of xamarin-android at compile time through some configuration.
  2. How can I add targets for .Net 6 / .Net 7 so it reflects in nuget package, any link to the related doc will be super useful?

@akoeplinger
Copy link
Member

akoeplinger commented Feb 23, 2023

  1. Can we make project choose netstandard 2.0 assembly instead of xamarin-android at compile time through some configuration.

No, the only option I can think of would be to remove the monoandroid folder from your nuget package so it always picks the netstandard2.0 one, but I assume this won't work because you likely have Android-specific code otherwise the monoandroid target doesn't make sense. There's a longstanding nuget feature request to override the selection which would be helpful here: NuGet/Home#7416

  1. How can I add targets for .Net 6 / .Net 7 so it reflects in nuget package, any link to the related doc will be super useful?

That depends on how your nuget package build works today. You'd need to build with the modern .NET SDK and set <TargetFramework>net6.0</TargetFramework> in your csproj file.

@sacOO7
Copy link
Author

sacOO7 commented Feb 23, 2023

Great, we will fix this as per your suggestion and will let you know if anything comes up !!!

Thanks again, this is really helpful : )

@sacOO7
Copy link
Author

sacOO7 commented Feb 23, 2023

There's a longstanding nuget feature request to override the selection which would be helpful here: NuGet/Home#7416

I think being able to choose the selection would be useful. At the same time, it will be great to enforce users to make them add explicit targets for .Net 6 and .Net 7.

@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Feb 24, 2023
akoeplinger added a commit to akoeplinger/runtime that referenced this issue Feb 24, 2023
…b.dll

The legacy Xamarin.Android version of mscorlib.dll differed a bit compared to the .NET Framework mscorlib.dll, mostly because of additions for .NET Standard 2.1 support.

This meant that an assembly which was compiled against that mscorlib expects types there but since we didn't have type-forwarders in our mscorlib.dll shim to point them to the right assembly you'd get a TypeLoadException when running on modern .NET 6 Android.

Fixes dotnet#82193

Should also fix dotnet/maui#5142, dotnet/maui#5078, dotnet/maui#3903
@akoeplinger
Copy link
Member

I've also just experimented with adding these missing type forwarders to the mscorlib.dll shim and it fixes the issue as well, i.e. the monoandroid assembly works.

I opened a PR, we'll see if we can maybe backport it to 7.0: #82618

@sacOO7
Copy link
Author

sacOO7 commented Feb 24, 2023

@akoeplinger wow, this is amazing : )

When can we expect this to get merged and available after release?

akoeplinger added a commit that referenced this issue Mar 1, 2023
…b.dll (#82618)

The legacy Xamarin.Android version of mscorlib.dll differed a bit compared to the .NET Framework mscorlib.dll, mostly because of additions for .NET Standard 2.1 support.

This meant that an assembly which was compiled against that mscorlib expects types there but since we didn't have type-forwarders in our mscorlib.dll shim to point them to the right assembly you'd get a TypeLoadException when running on modern .NET 6 Android.

Fixes #82193
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Mar 1, 2023
@marek-safar marek-safar modified the milestones: 8.0.0, 7.0.x Mar 3, 2023
akoeplinger added a commit to akoeplinger/runtime that referenced this issue Mar 8, 2023
…b.dll (dotnet#82618)

The legacy Xamarin.Android version of mscorlib.dll differed a bit compared to the .NET Framework mscorlib.dll, mostly because of additions for .NET Standard 2.1 support.

This meant that an assembly which was compiled against that mscorlib expects types there but since we didn't have type-forwarders in our mscorlib.dll shim to point them to the right assembly you'd get a TypeLoadException when running on modern .NET 6 Android.

Fixes dotnet#82193

(cherry picked from commit d8203e7)
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Mar 8, 2023
carlossanlop added a commit that referenced this issue Mar 9, 2023
…ity to mscorlib.dll and System.Drawing.Common.dll (#83137)

* Add more type-forwarders for Xamarin.Android compatibility to mscorlib.dll (#82618)

The legacy Xamarin.Android version of mscorlib.dll differed a bit compared to the .NET Framework mscorlib.dll, mostly because of additions for .NET Standard 2.1 support.

This meant that an assembly which was compiled against that mscorlib expects types there but since we didn't have type-forwarders in our mscorlib.dll shim to point them to the right assembly you'd get a TypeLoadException when running on modern .NET 6 Android.

Fixes #82193

(cherry picked from commit d8203e7)

* Add type-forwarders for Xamarin.Android compatibility to System.Drawing.Common.dll (#82839)

The legacy Xamarin.Android version of System.Drawing.Common.dll contained these types, add forwarders so we don't get a TypeLoadException when using an assembly compiled against that in modern .NET Android.

Fixes #82829

(cherry picked from commit e486f38)

* Use 7.0 version of the ApiCompat suppressions

* Fix diff

---------

Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com>
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Mar 9, 2023
@akoeplinger
Copy link
Member

@sacOO7 we merged the backport to the release/7.0 branch and is currently targeted for the 7.0.5 release.

@sacOO7
Copy link
Author

sacOO7 commented Mar 10, 2023

Thanks @akoeplinger, this is helpful 👍

@ghost ghost locked as resolved and limited conversation to collaborators Apr 9, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants