-
Notifications
You must be signed in to change notification settings - Fork 45
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
Assembly version mismatch, caused by netstandard1.6 support #34
Comments
can repro in FsAutocomplete| fusion log
|
``` Error Message: System.TypeInitializationException : The type initializer for 'FSharpLint.Framework.Configuration' threw an exception. ----> System.TypeInitializationException : The type initializer for '<StartupCode$FSharpLint-Core>.$Configuration' threw an exception. ----> System.IO.FileLoadException : Could not load file or assembly 'FParsecCS, Version=1.0.3.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040) ``` That's caused by bad packaging of FParsec ref stephan-tolksdorf/fparsec#34
I see @enricosada has some success with dual targetting as a workaround. Another workaround is to handle |
Multitargeting works because consumer projects will load the right assembly (net or netstandard) in all the project references chain. That mean I’ll send a PR to fix this here, adding netstandard2.0 too |
@enricosada Thanks. Also, aaaaah! I had tried multitargeting netstandard1.6 and netstandard2.0, which did not work. But I did not try also targeting netfx. I am curious whether you agree this is ultimately a .NET Framework bug, even though it is one you can work around in FParsec by multitargeting. As I understand it, net472 should support netstandard2.0 just as well as netcoreapp2.0 does. |
sent pr #38 to add |
…#38) create a modern package, use .net sdk, cleanup infra, add ci. ## Supported frameworks add support for `netstandard2.0` drop support for discontinued `net40-client` target framework. it's not used anymore in .NET >= 4.5 ref https://docs.microsoft.com/en-us/dotnet/framework/deployment/client-profile drop support for `netstandard1.6`, it's useful only in .NET Core v1. replaced by `netstandard2.0` drop support for `.NETPortable`( `portable-net45+win8+wp8+wpa81` ) target framework. the PCL profiles are replaced by .NET Standard. - the compiler defines `PCL` is not used anymore. The code is not yet removed because it's a big change, but because the compiler define is not set, the code is unused ## Dependencies pin `FSharp.Core` to be >= v4.3.4 for all target framework to simplify deps ## Projects add `global.json` to pin .net core sdk version to make build deterministic upgrade form FSharp.NET.Sdk style (deprecated in .NET Core Sdk 1.0) to .NET Sdk fsproj cleanup shared props and fsproj, using conventions of .NET Sdk: - refactor common properties in an automatically imported `Directory.Build.props` - move props near usage in projects - remove now useless FParsec.Samples.Common.targets - upgrade tests from netcoreapp2.0 to netcoreapp2.1 remove old VS11 projects, new projects works in VS ## Build script update `pack.ps1` powershell script, to use `dotnet` commands instead of msbuild/nuget nupkgs are generated in `~/bin/nupkg` ## CI Add appveyor: - run `pack.ps1` - version suffix autogenerated by buildId/branch/PR. no suffix if is a tag (so just tag to generate a stable version) - generated nupkgs are in the artifacts tab of appveyor, ready to download Add travis: - osx/ubuntu - run `dotnet build` on both `Release` and `Release-LowTrust` configurations - run tests only if `netcoreapp`. It can run also `net45` test using mono but i am too lazy to write the if in the travis script (but the matrix is there) ## Issues fix #34 (support `netstandard` and `net` tfms) fix #21 (just run `dotnet` commands, but replacing the powershell is easy too)
I'm having the same problem, though I suspect it has little to do with targeting 1.6 vs 2.0. This is from a decompilation of the FParsecCS assembly:
Notice it says 1.0.0.0 on the last line. ILSpy also recognizes the assembly as FParsecCS(1.0.0.0), which is probably why it'd fail to load in .net framework. I suspect the update to 2.0 somehow fixed whatever caused this, since that version is fixed in 1.1.0-RC. Here's the question though: given 1.1.0's status as not final, and that the 1.0.3 version is essentially unusable (for my specific scenario) given this error, is it safe to use 1.1.0-RC in production? |
I've just released the final 1.1.0 version, which codewise is identical to the RC release. |
I'm getting a very similar issue with FParsec 1.1.1, the issue seems to come down to the FParsec package having assemblies with different version numbers for different target frameworks (net45 = 1.0.0.0, netstandard2.0 = 1.1.1.0). Was it intentional that the net45 assembly has a different version number? It makes it difficult to consume a netstandard2.0 library that uses FParsec, from a net472 assembly. |
The net45 assembly uses the fixed version number 1.0.0.0 because it is strongly signed, while the netstandard2.0 is not. You'll find discussions on the signing in comments on older issues. |
Support for netstandard1.6 causes assembly binding trouble, at least when support for netstandard2.0 would be preferred.
Steps to reproduce
Suppose you have two F# (or C#) projects, namely a library
libfoo
and an applicationappbar
. libfoo targets netstandard2.0, and appbar targets .NET Framework 4.7.2.Also, suppose libfoo uses FParsec. In particular, libfoo depends upon the
FParsec
NuGet package, version 1.0.4-RC3. Also, libfoo must reference FParsec types, even if in a trivial way, to cause libfoo to load the FParsec assemblies.A suitable example libfoo.fs follows:
Finally, suppose appbar depends upon libfoo. In particular, appbar must load libfoo, by calling into libfoo.nonConst(). The last being non-constant is important; otherwise the compiler could optimize away the loading of the libfoo assembly.
Expected result
appbar calls libfoo.nonConst, and successfully receives a return value.
Actual result
appbar calling libfoo.nonConst causes an exception:
FileLoadException: Could not load file or assembly 'FParsecCS, Version=1.0.4.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
Environment
I am using recent Visual Studio 2017 (v15.8.7), and NuGet (v4.8.1).
Non-causes and non-fixes
Many things can be changed or added, and still trigger this bug:
1.0.4.0
, the AssemblyVersion tends to be set to1.0.0.0
. This surprised me. Regardless, changing AssemblyVersion to match AssemblyFileVersion/FileVersion does not solve the bug.Also, this issue affects every version of FParsec with netstandard1.6 support, namely from 1.0.3 beta upwards.
Also, FWIW, I needed two projects, the libfoo and appbar: I could not reproduce the issue with only one project.
Workarounds
Now, this issue can be avoided by changing libfoo to target .NET Framework (e.g. v4.7.2), or changing appbar to target netcoreapp (v1.0, v1.1, v2.0 or v2.1). Unfortunately, this is not always feasible.
The above fact suggests to me that this could be a bug in the .NET Framework's support of netstandard.
Nonetheless, it may be easier and faster to work around this issue in FParsec. In particular, the issue can be fixed if FParsec targets netstandard2.0 instead of netstandard1.6. Weirdly, and in support of my supposition this is a .NET Framework bug, it is not enough for FParsec to target netstandard2.0 in addition to netstandard1.6
Next steps
Would you be willing to target netstandard2.0 instead of netstandard1.6? And if so, would you prefer a pull request, or to implement the change yourself?
Moreover, please ping me if you have trouble building an unmodified FParsec with the recent version of Visual Studio I am using. In particular, as a separate issue, there are some changes which might be required to the way FSharp.Core is referenced.
The text was updated successfully, but these errors were encountered: