Azure / azure-cosmos-dotnet-v3

.NET SDK for Azure Cosmos DB for the core SQL API
MIT License
737 stars 494 forks source link

CosmosClient runtime exception if compiled with .NET native toolchain (on UWP only) #2049

Open mdbill opened 3 years ago

mdbill commented 3 years ago

Describe the bug CosmosClient instantiation runtime exception on UWP, only in Release build (or Debug but with 'compile with .NET native toolchain' checked) Works if uncheck 'compile with .NET native toochain' but of course this is required for any store app (release build) works on iOS and Android

To Reproduce Start with a new 'Blank App (Universal Windows)' template in Visual Studio Add : using Microsoft.Azure.Cosmos; and... var c = new CosmosClient(endpoint, key); // your favorite endpoint & key or emulator

build/run Release mode, (i.e. 'compile with .NET native toolchain')

Actual behavior throws exception

System.Configuration.ConfigurationErrorsException: 'An error occurred creating the configuration section handler for appSettings: The type 'System.Configuration.AppSettingsSection' cannot be found in assembly 'System.Configuration.ConfigurationManager, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'.'

TypeLoadException: The type 'System.Configuration.AppSettingsSection' cannot be found in assembly 'System.Configuration.ConfigurationManager, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'.

------ My app doesn't use this nuget, but if I install nuget: System.Configuration.ConfigurationManager 5.0, I get...

System.Configuration.ConfigurationErrorsException: 'Configuration system failed to initialize'

MissingMethodException: No parameterless constructor defined for this object.

Environment summary SDK Version: 3.9.1 preview (also tried latest 3.15.2 preview) I have another app that uses 3.15.0 (non-preview) I use preview because that app depends on the change feed pull model. OS Version (Windows)

j82w commented 3 years ago

You installed System.Configuration.ConfigurationManager 5.0 but if you noticed the exception message is expecting System.Configuration.ConfigurationManager, Version=4.0.1.0. Can you please try using version 4.0.1.0? It likely the version 5 has breaking changes that are not compatible with version 4.

mdbill commented 3 years ago

My app doesn't use ConfigurationManger, so above I showed the error I get with no nuget and then how the error changes if I install 5.0. The only available versions are 4.4 and up.

j82w commented 3 years ago

The version is actually 4.5.0. https://github.com/Azure/azure-cosmos-dotnet-v3/blob/edf3e77838e260ef84691d0d490376afc2a9c3b2/Microsoft.Azure.Cosmos/src/Microsoft.Azure.Cosmos.csproj#L130

mdbill commented 3 years ago

With no nuget or explicitly installing 4.5.0, I get the same error (the 1st ones):

System.Configuration.ConfigurationErrorsException: 'An error occurred creating the configuration section handler for appSettings: The type 'System.Configuration.AppSettingsSection' cannot be found in assembly 'System.Configuration.ConfigurationManager, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'.'

TypeLoadException: The type 'System.Configuration.AppSettingsSection' cannot be found in assembly 'System.Configuration.ConfigurationManager, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'.

I was only pointing out that the error changes with 5.0.

ealsur commented 3 years ago

Is this a .NET Framework application or NET Core or NET 5? Do you have multiple projects that depend one on the other that might have different package versions?

It sounds like you might be having a dependency redirection issue? Can you provide a CSPROJ that can help repro the issue?

mdbill commented 3 years ago

To Reproduce, I created a new Xamarin.Forms mobile app (Blank app) from the template in VS 16.8.2 and added cosmos 3.15.0. Then, using cosmos, in MainPage.xaml.cs, add.... var c = new CosmosClient(endpoint, key); Run Release x64 and you get the exception.

ealsur commented 3 years ago

Cannot repro, I used a new blank Xamarin.Forms app with Android. It builds on Release/x64 without issues:

image

Using SDK 3.15.0, here is the CSPROJ:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <ProduceReferenceAssembly>true</ProduceReferenceAssembly>
    <Platforms>AnyCPU;x64</Platforms>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <DebugType>portable</DebugType>
    <DebugSymbols>true</DebugSymbols>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <DebugType>portable</DebugType>
    <DebugSymbols>true</DebugSymbols>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Azure.Cosmos" Version="3.15.0" />
    <PackageReference Include="Xamarin.Forms" Version="5.0.0.1558-pre3" />
    <PackageReference Include="Xamarin.Essentials" Version="1.5.3.2" />
  </ItemGroup>
</Project>

I only added the SDK package to the base project (the one that contains the MainPage.xaml.cs file).

Please provide a CSPROJ or project we can use to reproduce, the File > New Project template has no issues.

mdbill commented 3 years ago

Oops, you missed from line #1 of the OP.. "fails on UWP" and line #3 "works on iOS and Android" And also note: it builds fine on UWP too. It's an exception at runtime.

mdbill commented 3 years ago

And just in case it matters, I use the latest, stable Xamarin.Forms (4.8.0.1687)

mdbill commented 3 years ago

This issue seems similar... https://docs.microsoft.com/en-us/answers/questions/180208/uwp-app-does-not-work-in-release-x64-build-but-in.html

mdbill commented 3 years ago

I was able to instantiate DocumentClient from the V2 SDK (using the blank sample app), but I have 5 apps (4 in production) that use V3. Please help!

mdbill commented 3 years ago

Also tried the blank UWP app template (no Xamarin forms) Still the same runtime exception. Seems hard to believe that no UWP store app can connect to Cosmos DB (using sdk V3,) but that's how it looks. Can anyone confirm this?

mdbill commented 3 years ago

Please provide a CSPROJ or project we can use to reproduce, the File > New Project template has no issues.

Have you seen the updates over the past 3 weeks which explain how to reproduce the problem?

ealsur commented 3 years ago

@mdbill You mentioned the DocumentClient works, which Nuget package and version are you using? Is it Microsoft.Azure.DocumentDB or Microsoft.Azure.DocumentDB.Core?

Are you using Resource Tokens in your UWP applications or using the account keys? If using the account keys, how do you account for key rotations or potential access to those keys by someone decompiling the app?

Normally the pattern we see is users of mobile apps either use a Resource Token broker if they are connecting directly or go through Web APIs (potentially with a load balancer that distributes the requests geographically based on the location of the client application). I wonder what's your use case?

I'll try the comments above, I'm no Xamarin or UWP expert, so no idea what could be causing this.

j82w commented 3 years ago

Is the ServiceInterop.dll being included? The SDK assumes that the dll is always available even if it is not on a supported platform.

https://github.com/Azure/azure-cosmos-dotnet-v3/blob/bfb3d8f588a70cf6072284dc9e17045cacb9ae6c/Microsoft.Azure.Cosmos/src/CosmosClient.cs#L109

mdbill commented 3 years ago

Is the ServiceInterop.dll being included?

Microsoft.Azure.Cosmos.ServiceInterop.dll is in the /bin/x64/Release directory

mdbill commented 3 years ago

@mdbill You mentioned the DocumentClient works, which Nuget package and version are you using? Is it Microsoft.Azure.DocumentDB or Microsoft.Azure.DocumentDB.Core?

I used the lastest with '.Core' 2.13.1. And I simply got past that one instantiation, just to confirm it's a V3 problem. I rely on changefeed in V3 and I don't know that I could even use V2 if I was forced to.

Are you using Resource Tokens in your UWP applications or using the account keys? If using the account keys, how do you account for key rotations or potential access to those keys by someone decompiling the app?

Normally the pattern we see is users of mobile apps either use a Resource Token broker if they are connecting directly or go through Web APIs (potentially with a load balancer that distributes the requests geographically based on the location of the client application). I wonder what's your use case?

I don't keep any data longer than 1 day. Cosmos is used as a realtime game server. So I had no concern for securing access. But thanks for reminding me! My 5th app (in beta) will need that.

mdbill commented 3 years ago

I'll try the comments above, I'm no Xamarin or UWP expert, so no idea what could be causing this.

I spent (another) 10 hours trying different things. Narrowed it down to this. I tried a blank app and added the nuget for ConfigurationManager, and an app.config file. then just...

using System.Configuration;

and... string sAttr= ConfigurationManager.AppSettings.Get("Key0");

Again, works in Debug mode. Not Release (with .net native toolchain) Crashes at runtime. So it appears that ConfigurationManager is not supported (or broken) on UWP with .net native toolchain. (A console app works ) So... CosmosDB (V3) fails since it introduces a dependency on ConfigurationManager.

Can you remove that dependency?

Can you confirm that it is impossible to get any Windows Store app to connect to Cosmos using V3 SDK?

mdbill commented 3 years ago

For the record, switching to the V2 SDK also has (different) problems with Release mode (I reported it to that team as well).

So, no UWP apps are capable of using Cosmos?!?....unless someone disagrees? Is anyone working on this? Am I reporting this in the right place? It seems like this should get more attention.

mdbill commented 3 years ago

Am I in the right place with this bug report? This is a critical issue for me -- seems like for everyone since no one has disagreed that the blank sample crashes.

ealsur commented 3 years ago

@mdbill I understand the frustration. I don't think we can remove a dependency like ConfigurationManager, it might be considered a breaking change.

Like you said, this sounds like it's a problem with that package, which in theory should work, as it is marked as NetStandard 2.0. If it was not meant to work on some platform, the NetStandard documentation says it should throw a PlatformNotSupportedException, but it looks like it's not the case. We follow these guidelines, and we do catch any potential issues when they are excepted (for example, WASM platform has some APIs on HttpClient that are not supported and we catch the exception and workaround in those cases).

The SDK is not often used in client app that run on the device itself due to the security problem already mentioned, that would lower the priority of this particular issue. This is the right place and it is being tracked but its priority over other features or fixes might be lower due to this particular anti-pattern. Normally your devices should be talking to a API layer that provides service to the apps, see the architecture at: https://docs.microsoft.com/en-us/azure/cosmos-db/use-cases#gaming

mdbill commented 3 years ago

Thx for the detailed response. I wanted someone to verity I wasn't doing anything wrong on my end. Instead....

Microsoft's official word is that the Microsoft Cosmos DB is not supported on Microsoft's Universal Windows platform. It has never worked on UWP, so there is no rolling back to another version. Nor is anyone actively trying to fix support for UWP.

Shouldn't CosmosDB throw PlatformNotSupportedException and the documentation be updated to reflect this?

It seems so close to working since everything is fine in Debug mode. Anyone with a workaround suggestion? Maybe supplying an app.config that would keep the ConfigurationManager happy? I tried, but maybe something with [MethodImpl(methodImplOptions: MethodImplOptions.NoOptimization)]

P.S. I quickly tried a WPF sample app (where .net native is not a thing), but 'Optimize Code' still is. This failed in Release mode too. It works in Debug :(

mdbill commented 3 years ago

I was able to remove the offending lines and successfully connected (call to CosmosClient) However, it still crashes eventually I assume due to the cosmos.direct.dll depending on ConfigurationManager too. Is the source code for Microsoft.Azure.Cosmos.Direct.dll available?

There are 4 places in the code that look like below. Every access to ConfigurationManager.AppSettings crashes and they are all wrapped in these #if NETSTANDARD conditional flags.

if !(NETSTANDARD15 || NETSTANDARD16)

if NETSTANDARD20

        // GetEntryAssembly returns null when loaded from native netstandard2.0
        if (System.Reflection.Assembly.GetEntryAssembly() == null)
        {

endif

            // For tests we want to allow stronger consistency during construction or per call
            string allowOverrideStrongerConsistencyConfig = System.Configuration.ConfigurationManager.AppSettings[DocumentClient.AllowOverrideStrongerConsistency];
mdbill commented 3 years ago

If I use Gateway mode, then cosmos.direct.dll doesn't get used and doesn't crash. So that, combined with re-building my own CosmosDB with offending code removed (above). I think I have it working. Score +1 for open source. This workaround doesn't close this bug report.

andreslon commented 3 years ago

any solution on this error?? getting the same message from .NET 5.0 API

System.Configuration.ConfigurationErrorsException: 'Configuration system failed to initialize' ConfigurationErrorsException: Unrecognized configuration section system.web. (.....API\bin\Debug\net5.0-windows\abc.API.dll.config line 3)