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

[8.0] HybridGlobalization problem in Blazor WASM targeting .NET 8 and published with .NET 9 SDK #109951

Open
1 task done
menees opened this issue Nov 19, 2024 · 17 comments
Open
1 task done
Assignees
Labels
arch-wasm WebAssembly architecture area-System.Globalization os-browser Browser variant of arch-wasm
Milestone

Comments

@menees
Copy link

menees commented Nov 19, 2024

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

I have a Blazor WASM project that targeted .NET 8. After I installed the VS 2022 17.12 update, my app stopped working when published to a production server. The stack trace reported in the browser's Console window was:

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: TypeInitialization_Type, Menees.Chords.ChordProDirectiveLine
System.TypeInitializationException: TypeInitialization_Type, Menees.Chords.ChordProDirectiveLine
 ---> System.TypeInitializationException: TypeInitialization_Type, Menees.Chords.Parsers.ChordParser
 ---> System.PlatformNotSupportedException: PlatformNotSupported_HybridGlobalization, HashCode
   at System.Globalization.CompareInfo.GetHashCodeOfStringCore(ReadOnlySpan`1 , CompareOptions )
   at System.Globalization.CompareInfo.GetHashCode(ReadOnlySpan`1 , CompareOptions )
   at System.Globalization.CompareInfo.GetHashCode(String , CompareOptions )
   at System.CultureAwareComparer.GetHashCode(String )
   at System.Collections.Generic.HashSet`1[[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].AddIfNotPresent(String , Int32& )
   at System.Collections.Generic.HashSet`1[[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Add(String )
   at Menees.Chords.Parsers.ChordParser..cctor()
   Exception_EndOfInnerExceptionStack
   at Menees.Chords.ChordProDirectiveLine..cctor()
   Exception_EndOfInnerExceptionStack
   at Menees.Chords.Parsers.DocumentParser.ParseLines(TextReader reader)
   at Menees.Chords.Parsers.DocumentParser.Parse(TextReader reader)
   at Menees.Chords.Document.Parse(String text, DocumentParser parser)
   at Menees.Chords.Web.Index.ConvertInput()
   at Menees.Chords.Web.Index.OnInitializedAsync()
   at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()

Others have reported similar problems on StackOverflow here.

The VS 17.12 update removed the .NET 8.0.404 SDK and replaced it with the .NET 9.0.100 SDK. Something isn't working right with HybridGlobalization in that scenario.

I first worked around the problem by creating a global.json file and manually installing the .NET 8.0.404 SDK again (as suggested by Dimitris Maragkos). That commit can be seen here.

Later I worked around the problem by upgrading the project to target .NET 9 and publish with the .NET 9.0.100 SDK. That commit can be seen here.

The production problem only occurs when trying to target .NET 8 and publish with the .NET 9.0.100 SDK. That combination works in VS at build and debug time. It only fails when published. And my app does NOT opt-in with <HybridGlobalization>true</HybridGlobalization> as discussed here. I'm just using StringComparer.CurrentCultureIgnoreCase from a static initializer here.

Expected Behavior

A Blazor WASM app that targets .NET 8 should be publilshable using the .NET 9 SDK without throwing PlatformNotSupportedException: PlatformNotSupported_HybridGlobalization, HashCode at runtime.

Steps To Reproduce

No response

Exceptions (if any)

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: TypeInitialization_Type, Menees.Chords.ChordProDirectiveLine
System.TypeInitializationException: TypeInitialization_Type, Menees.Chords.ChordProDirectiveLine
 ---> System.TypeInitializationException: TypeInitialization_Type, Menees.Chords.Parsers.ChordParser
 ---> System.PlatformNotSupportedException: PlatformNotSupported_HybridGlobalization, HashCode
   at System.Globalization.CompareInfo.GetHashCodeOfStringCore(ReadOnlySpan`1 , CompareOptions )
   at System.Globalization.CompareInfo.GetHashCode(ReadOnlySpan`1 , CompareOptions )
   at System.Globalization.CompareInfo.GetHashCode(String , CompareOptions )
   at System.CultureAwareComparer.GetHashCode(String )
   at System.Collections.Generic.HashSet`1[[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].AddIfNotPresent(String , Int32& )
   at System.Collections.Generic.HashSet`1[[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Add(String )
   at Menees.Chords.Parsers.ChordParser..cctor()
   Exception_EndOfInnerExceptionStack
   at Menees.Chords.ChordProDirectiveLine..cctor()
   Exception_EndOfInnerExceptionStack
   at Menees.Chords.Parsers.DocumentParser.ParseLines(TextReader reader)
   at Menees.Chords.Parsers.DocumentParser.Parse(TextReader reader)
   at Menees.Chords.Document.Parse(String text, DocumentParser parser)
   at Menees.Chords.Web.Index.ConvertInput()
   at Menees.Chords.Web.Index.OnInitializedAsync()
   at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()

.NET Version

9.0.100

Anything else?

This started after installing the VS 2022 17.12 update, which removed the .NET 8.0.404 SDK. I had to manually reinstall that SDK to continue to target and publish .NET 8 versions that worked.

dotnet --info
.NET SDK:
 Version:           9.0.100
 Commit:            59db016f11
 Workload version:  9.0.100-manifests.c6f19616
 MSBuild version:   17.12.7+5b8665660

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.22631
 OS Platform: Windows
 RID:         win-x64
 Base Path:   C:\Program Files\dotnet\sdk\9.0.100\

.NET workloads installed:
 [wasm-tools-net6]
   Installation Source: VS 17.12.35506.116
   Manifest Version:    9.0.0/9.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\9.0.100\microsoft.net.workload.mono.toolchain.net6\9.0.0\WorkloadManifest.json
   Install Type:              Msi

 [wasm-tools]
   Installation Source: VS 17.12.35506.116
   Manifest Version:    9.0.0/9.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\9.0.100\microsoft.net.workload.mono.toolchain.current\9.0.0\WorkloadManifest.json
   Install Type:              Msi

 [aspire]
   Installation Source: VS 17.12.35506.116
   Manifest Version:    8.2.2/8.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.aspire\8.2.2\WorkloadManifest.json
   Install Type:              Msi

Configured to use loose manifests when installing new manifests.

Host:
  Version:      9.0.0
  Architecture: x64
  Commit:       9d5a6a9aa4

.NET SDKs installed:
  8.0.404 [C:\Program Files\dotnet\sdk]
  9.0.100 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 8.0.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 9.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 8.0.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 9.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.1.32 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 8.0.11 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 9.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found:
  x86   [C:\Program Files (x86)\dotnet]
    registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment variables:
  Not set

global.json file:
  C:\Dev\Repos\Chords\global.json

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download
@javiercn javiercn transferred this issue from dotnet/aspnetcore Nov 19, 2024
@dotnet-issue-labeler dotnet-issue-labeler bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Nov 19, 2024
@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Nov 19, 2024
@javiercn javiercn added arch-wasm WebAssembly architecture and removed untriaged New issue has not been triaged by the area owner needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Nov 19, 2024
Copy link
Contributor

Tagging subscribers to 'arch-wasm': @lewing
See info in area-owners.md if you want to be subscribed.

Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-globalization
See info in area-owners.md if you want to be subscribed.

@Ruben-J
Copy link

Ruben-J commented Nov 20, 2024

Got exactly same problem with a Blazor wasm application that is targeting .NET 8

@maraf maraf added the os-browser Browser variant of arch-wasm label Nov 20, 2024
@maraf maraf added this to the 9.0.x milestone Nov 20, 2024
@maraf
Copy link
Member

maraf commented Nov 20, 2024

@ilonatommy Can you please verify if there is some misalignment between between .NET 9 SDK and .NET 8 runtime pack / workload for hybrid globalization? We have other problem with satellite assemblies #109604, but this one looks different

@NoahBPeterson
Copy link

My issue (Closed now, as I learned it was not an issue with the Fluxor library, but with dotnet itself): mrpmorris/Fluxor#515

I ran into this exact issue. This is the second Blazor-breaking regression in two years, and both cost me a week of work.

@CeloScheibe
Copy link

I can confirm the same issue on our side. This is currently causing issues during our deployment as the Microsoft-hosted agents are starting to be updated as well.

Our workaround is to also the global.json file to specify the target sdk during the "dotnet publish" command execution. We had issues in getting the pipeline agent to read the file because it needs to be created within the working directory of the agent, which was outside our repository files. A proposed work-around would be this:

  - task: PowerShell@2
    displayName: 'Create global.json'
    inputs:
      targetType: "inline"
      script: |
        # This is necessary due to an issue when building using the dotnet 9 SDK
        # This will create the global.json within the current workingDir which is needed for publish
        dotnet new globaljson --sdk-version 8.0.0 --roll-forward latestFeature

This task creates the global.json file with version 8.0.X in the current working directory of the agent. Any following tasks will now be able to use it. I used an inline powershell scripts because I couldn't figure out how the "custom" command syntax works in the DotNetCoreCLI@2 task.

Related information: https://stackoverflow.com/questions/68896612/working-directory-parameter-of-dotnetcorecl-publish-step

@Ruben-J
Copy link

Ruben-J commented Nov 22, 2024

I can confirm the same issue on our side. This is currently causing issues during our deployment as the Microsoft-hosted agents are starting to be updated as well.

Our workaround is to also the global.json file to specify the target sdk during the "dotnet publish" command execution. We had issues in getting the pipeline agent to read the file because it needs to be created within the working directory of the agent, which was outside our repository files. A proposed work-around would be this:

  - task: PowerShell@2
    displayName: 'Create global.json'
    inputs:
      targetType: "inline"
      script: |
        # This is necessary due to an issue when building using the dotnet 9 SDK
        # This will create the global.json within the current workingDir which is needed for publish
        dotnet new globaljson --sdk-version 8.0.0 --roll-forward latestFeature

This task creates the global.json file with version 8.0.X in the current working directory of the agent. Any following tasks will now be able to use it. I used an inline powershell scripts because I couldn't figure out how the "custom" command syntax works in the DotNetCoreCLI@2 task.

Related information: https://stackoverflow.com/questions/68896612/working-directory-parameter-of-dotnetcorecl-publish-step

Why don't you just use UseDotNet (https://learn.microsoft.com/en-gb/azure/devops/pipelines/tasks/reference/use-dotnet-v2?view=azure-pipelines&viewFallbackFrom=azure-devops) at the beginning of your pipeline.

- task: UseDotNet@2
      inputs:
        packageType: 'sdk'
        version: '8.x'

@ilonatommy
Copy link
Member

Sorry for the delay, I was away. I am looking into it, from some reason net8 trims the GetHashCodeOfStringCore method to

    private int GetHashCodeOfStringCore([In] ReadOnlySpan<char> obj0, [In] CompareOptions obj1)
    {
      if (true);
      throw new PlatformNotSupportedException(CompareInfo.GetPNSEText("HashCode"));
    }

where true is

internal static bool Hybrid { get; } = AppContextConfigHelper.GetBooleanConfig("System.Globalization.Hybrid", "DOTNET_SYSTEM_GLOBALIZATION_HYBRID");
.

When we disable trimming (not recommended), the published app works fine. I will try to find out about the details behind it as soon as I can.

@pragmaeuge
Copy link

Hi, we have tried to publish our app disabling trimming from Blazor webassembly client project, unfortunatly with no success. In our case, the problem arises on rendering a chart component, which relies on HybridGlobalization (ScottPlot.NET).
Hope bug fix will be released soon.

Thank you!

@ilonatommy
Copy link
Member

ilonatommy commented Nov 26, 2024

@pragmaeuge, do I understand it correctly that in your case the project sets HybridGlobalization=true? The issue reported here was about HybridGlobalization=false and the fix and reproduction was for that case.

And my app does NOT opt-in with <HybridGlobalization>true</HybridGlobalization>

You might be facing a different issue. Tell me more about it.

@ilonatommy
Copy link
Member

ilonatommy commented Nov 26, 2024

@pragmaeuge, I used ScottPlot5 project from your repo to reproduce and I confirm that the change from #110183 helped. I cannot see HybridGlobalization being set in your repository, so probably

relies on HybridGlobalization

was a misunderstanding, maybe you meant "relies on System.Globalization library". In case my assumptions are incorrect or I checked a wrong project, let me know.

Edit: interesting part of it is that adding

<PropertyGroup>
   <PublishTrimmed>false</PublishTrimmed>
</PropertyGroup>

in the project I quoted, also removes the error. Now I would like to know where lies the difference between me using PublishTrimmed=false and your using it.

@pragmaeuge
Copy link

Hi,
i think you are correct.
At the moment we have some problems in applying the workaround: for currently unknown reasons we are experimenting issues in publishing the project using the Visual Studio IDE, i think we experimented too much with some settings, in a desperate attempt to solve the original problem...

Thank you very much to have dig deeper in our issue, we have much appreciated it.

@ilonatommy
Copy link
Member

Let me list a more detailed chain of events that made this issue surface only now.

@ilonatommy ilonatommy changed the title HybridGlobalization problem in Blazor WASM targeting .NET 8 and published with .NET 9 SDK [8.0] HybridGlobalization problem in Blazor WASM targeting .NET 8 and published with .NET 9 SDK Nov 27, 2024
@DaveVW-AWE
Copy link

Having the same issue with our blazor apps after upgrading VS 2022 to 17.12

@ilonatommy
Copy link
Member

@DaveVW-AWE, the backported PR should be in net8 with January release. For now, please consider discussed workaround of rolling back to sdk8 or, in case it's possible, updating the project to net9.

@elylv
Copy link

elylv commented Dec 2, 2024

Having some issues getting this workaround to work. We're not using DevOps, but have tried placing that particular global.json in our solution root, and individually in out Client/Server/Shared directories, but to no avail. Can someone share how to get the workaround to work when using Visual Studio and its standard Publish process?

@DralFire
Copy link

DralFire commented Dec 2, 2024

At the end and after a long time of frustration, the solucion was do upgrate to NET 9

https://stackoverflow.com/questions/78700614/blazor-wasm-aggregateexception-ctor-defaultmessage-platformnotsupported-hybrid

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arch-wasm WebAssembly architecture area-System.Globalization os-browser Browser variant of arch-wasm
Projects
None yet
Development

No branches or pull requests