Bug 58549 - We load multiple versions of the same assembly
Summary: We load multiple versions of the same assembly
Status: RESOLVED FIXED
Alias: None
Product: Installers
Classification: Mono
Component: macOS Installer ()
Version: unspecified
Hardware: PC Mac OS
: Low normal
Target Milestone: Future Cycle (TBD)
Assignee: Alexis Christoforides
URL:
Depends on:
Blocks:
 
Reported: 2017-08-02 16:52 UTC by Miguel de Icaza [MSFT]
Modified: 2018-01-02 13:18 UTC (History)
5 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
The sample that includes a reference to 4.4.0.0 (94.91 KB, application/x-gzip)
2017-08-02 16:52 UTC, Miguel de Icaza [MSFT]
Details
a.exe.config for the repro (673 bytes, application/xml)
2017-08-02 17:18 UTC, Aleksey Kliger
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description Miguel de Icaza [MSFT] 2017-08-02 16:52:42 UTC
Created attachment 23988 [details]
The sample that includes a reference to 4.4.0.0

On MacOS, the following code ends up loading two versions of FSharp.Core, version 4.4.1.0 and 4.4.0.0 which makes this program throw an exception.

Unpack the project, and type make.

What happens is that the resulting executable contains a reference to FSharp.Core 4.4.1.0, while the library that we include references 4.4.0.0, and they both get loaded, leading to the error.

I think that we need some sort of runtime policy to say “Hey bae, 4.4.1.0 is totes compat with 4.4.0.0”

For this repro to work, you need your system GAC to contain an FSharp.Core 4.4.1.0, like this:

/Library/Frameworks/Mono.framework/Versions/5.2.0/lib/mono/gac/FSharp.Core/4.4.1.0__b03f5f7f11d50a3a/FSharp.Core.dll
Comment 1 Miguel de Icaza [MSFT] 2017-08-02 16:57:12 UTC
Perhaps FSharp.Core needs to be listed here:

static const AssemblyVersionMap framework_assemblies [] = {
Comment 2 Miguel de Icaza [MSFT] 2017-08-02 17:09:13 UTC
The difference is that .NET does not have FSharp.Core in the GAC.

If I remove my FSharp.Core from the GAC, and instead reference manually FSharp.Core.dll 4.1.0.0 it works.   And this means that FSharp.Core seems to resolve the 4.4.0.0 request from the XPlot.GoogleCharts.dll
Comment 3 Aleksey Kliger 2017-08-02 17:18:32 UTC
Created attachment 23990 [details]
a.exe.config for the repro

The workaround in Comment 2 only works with mono's legacy loader which is lax about versions of strong named assemblies - the legacy loader will load the first FSharp.Core.dll that it finds regardless of its version.   The strict loader `mono --assembly-loader=strict` will still cause the sample program to fail.

The correct solution is to bundle a rebinding file (a.exe.config) that remaps 4.4.0.0 requests to 4.4.1.0.  (Attached)

Using `mono --assembly-loader=strict` is the correct .net framework-compatible behavior.
Comment 4 Miguel de Icaza [MSFT] 2017-08-02 19:29:28 UTC
I think that --assembly-loader=strict is stricted than it needs to be, compared to .NET desktop.

This is what I did.   To mimic the .NET scenario, I removed FSharp.Core from the GAC, and ran the program again, and it works just fine on Mono on Mac, that is: the a.exe program references a type from FSharp.Core 4.4.1.0 and the intermediate XPlot.GoogleCharts.dll which in turn references 4.4.0.0.

The code runs just fine.

If I pass --assembly-loader=strict it fails on MOno, but works on .NET

------

Now, with the FSharp.Core in the GAC, if I load the FSharp.Core.dll 4.4.1.0 manually from disk, with a call to Assembly.LoadFrom ("FullPath-to-it") and run the program, *even* if there is a GAC, it works - just like it does on .NET.

And if I pass --assembly-loader=strict, it fails.

So in summary:

* --assembly-loader=strict it is stricter than .NET likely due to some scenarios we have not taken into consideration.
* We shot ourselves in the foot by putting FSharp.Core in the GAC.
Comment 5 Rodrigo Kumpera 2017-08-07 22:33:56 UTC
This is a packaging problem, moving to the right category.
Comment 6 Alexander Köplinger [MSFT] 2018-01-02 13:18:10 UTC
FSharp.Core was removed from the GAC in https://github.com/mono/mono/pull/6295 so this should be fixed now.