-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Changes to the msbuild extensions targets that will enable copying the shims for net471 case #1712
Conversation
…e shims for net471 case
build/DependencyVersions.props
Outdated
@@ -13,7 +13,7 @@ | |||
<NuGetVersion>4.5.0-preview2-4529</NuGetVersion> | |||
<NewtonsoftJsonVersion>9.0.1</NewtonsoftJsonVersion> | |||
<SystemReflectionMetadataVersion>1.4.2</SystemReflectionMetadataVersion> | |||
<NETStandardLibraryNETFrameworkVersion>2.0.1-servicing-25708-01</NETStandardLibraryNETFrameworkVersion> | |||
<NETStandardLibraryNETFrameworkVersion>2.0.1-servicing-25708-01</NETStandardLibraryNETFrameworkVersion> <!-- Once we have a new version of this package available, this version will have to be updated --> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has to change in the cli repo as well. This only controls what the sdk uses to test itself
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noted, I'll make sure it changes in the CLI repo as well.
|
||
<!-- if any reference depends on netstandard and it is not inbox, add references and implementation assemblies for netstandard2.0 --> | ||
<ItemGroup Condition="'$(DependsOnNETStandard)' == 'true' AND '$(NETStandardInbox)' != 'true'"> | ||
<ItemGroup Condition="'$(DependsOnNETStandard)' == 'true' AND '$(NETStandardInbox)' != 'true' AND '$(_TargetFrameworkVersionWithoutV)' != '4.7.1'"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
< 4.7.1 ?
Or move the 4.7.1 special work in a single place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
1912bdf
to
9fc5e5a
Compare
9fc5e5a
to
bf8f996
Compare
$"{testProject.Name}.pdb", | ||
$"{netStandardProject.Name}.dll", | ||
$"{netStandardProject.Name}.pdb", | ||
"System.Diagnostics.DiagnosticSource.dll" // This library will get pulled in as part of the closure of the ns16 project and will be copyied because it's not inbox. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AlexGhiondea I believe this might actually be a bug on the framework, so we might want to include this file inbox on 472.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't blindly include that inbox. Please consult with @vancem first as I know they were trying to keep it out of box.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd use the same comment here as in the previous test: // This is an implementation dependency of the System.Net.Http package, which won't get conflict resolved out
I'm also pretty sure we don't want to include this inbox. It's an implementation dependency of the OOB version of System.Net.Http. Conflict resolution will pick the support package of the Http library, but it doesn't know that this dependency is no longer needed.
If you want to consider making it so that this library isn't copied, please file a bug for that in the sdk repo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good I'll update it as requested.
.NET 4.7.1 has support for .NET Standard 2.0 built-in, so most of the facades aren't necessary. However, the assembly versions of a few set of assemblies | ||
do not yet match the ones shipped by the support package. This means that the versions from the contract NuGet packages would be preferred to the in-box | ||
version (which is newer). So if there is a dependency on netstandard.dll, we use the 4.2.0.0 version of the DLLs from the .NET Standard 2.0 "facades". | ||
(Though these DLLs are not actually facades, they contain the implementation.) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do all of them contain implementation? Are the version numbers for all of them 4.2.0.0?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, some are partial facades, and some are full facades so I'll update the comment
|
||
<!-- | ||
.NET 4.7.1 has support for .NET Standard 2.0 built-in, so most of the facades aren't necessary. However, the assembly versions of a few set of assemblies | ||
do not yet match the ones shipped by the support package. This means that the versions from the contract NuGet packages would be preferred to the in-box |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest updating this to say: "do not yet match the ones shipped in the support package for .NET Standard 2.0 on .NET 4.7 and below. This means that .NET 4.7 or lower libraries might have references to higher versions of these assemblies than are available in-box in .NET 4.7, leading to assembly loading errors."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will change.
|
||
<!-- if any reference depends on netstandard and it is not inbox, add references and implementation assemblies for netstandard2.0 --> | ||
<ItemGroup Condition="'$(DependsOnNETStandard)' == 'true' AND '$(NETStandardInbox)' != 'true'"> | ||
<ItemGroup Condition="'$(DependsOnNETStandard)' == 'true' AND '$(NETStandardInbox)' != 'true' AND '$(_TargetFrameworkVersionWithoutV)' < '4.7.1'"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the additional check that the target framework version is less than 4.7.1 necessary? NETStandardInbox == false
should imply that the target framework version is less than 4.7.1.
Or is this there in case people explicitly set NETStandardInbox
to false in their 4.7.1 projects as a workaround for this issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or is this there in case people explicitly set NETStandardInbox to false in their 4.7.1 projects as a workaround for this issue?
Yes that is the case. Initially I had it just with !=
but got a comment saying that in case people override that value, we should make sure this logic doesn't kick in for 4.7.2+
public void It_builds_a_net471_app() | ||
{ | ||
// https://github.com/dotnet/sdk/issues/1625 | ||
if (!Net471ReferenceAssembliesAreInstalled()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you run all these tests locally (with the reference assemblies installed)? We won't get any coverage for these tests on the CI machines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes ran all, and they all passed. And I do have 4.7.1.
@@ -127,14 +159,120 @@ public void It_does_not_include_facades_from_nuget_packages() | |||
outputDirectory.Should().OnlyHaveFiles(new[] { | |||
$"{testProject.Name}.exe", | |||
$"{testProject.Name}.pdb", | |||
|
|||
// Remove these two once https://github.com/dotnet/sdk/issues/1647 is fixed | |||
|
|||
"System.Net.Http.dll", | |||
"System.IO.Compression.dll", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest adding a comment explaining why these two libraries are included. My understanding is that these were the only contracts from .NET Standard 1.x that have a higher version than what shipped in .NET 4.7.1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, that is why. I'll add a comment.
$"{testProject.Name}.pdb", | ||
$"{netStandardProject.Name}.dll", | ||
$"{netStandardProject.Name}.pdb", | ||
"System.Diagnostics.DiagnosticSource.dll" // This library will get pulled in as part of the closure of the ns16 project and will be copyied because it's not inbox. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd use the same comment here as in the previous test: // This is an implementation dependency of the System.Net.Http package, which won't get conflict resolved out
I'm also pretty sure we don't want to include this inbox. It's an implementation dependency of the OOB version of System.Net.Http. Conflict resolution will pick the support package of the Http library, but it doesn't know that this dependency is no longer needed.
If you want to consider making it so that this library isn't copied, please file a bug for that in the sdk repo.
} | ||
|
||
[Fact] | ||
public void It_does_not_include_shims_when_app_references_471_library() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest also referencing a .NET 4.6.1 library in this test (either in addition to the 4.7.1 library, or making the test a Theory
and running it for different referenced framework versions.
|
||
static bool Net471ReferenceAssembliesAreInstalled() | ||
{ | ||
var net461referenceAssemblies = ToolLocationHelper.GetPathToDotNetFrameworkReferenceAssemblies(TargetDotNetFrameworkVersion.Version461); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest adding a comment explaining this, ie: The version of the MSBuild libraries we are referencing doesn't have an enum value for .NET 4.7.1. So we use the MSBuild API to find the path to the 4.6.1 reference assemblies, and locate the 4.7.1 reference assemblies relative to that.
version (which is newer). So if there is a dependency on netstandard.dll, we use the 4.2.0.0 version of the DLLs from the .NET Standard 2.0 "facades". | ||
(Though these DLLs are not actually facades, they contain the implementation.) | ||
do not yet match the ones shipped in the support package for .NET Standard 2.0 on .NET 4.7 and below. This means that .NET 4.7 or lower libraries might have | ||
references to higher versions of these assemblies than are available in-box in .NET 4.7, leading to assembly loading errors. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add this at the end: So if there is a dependency on netstandard.dll, we include DLLs for .NET 4.7.1 from the support package to avoid these errors.
Is this fully resolved? We ran into an issue where w3wp started crashing with
And when inspecting the type it failed on, it was always one which used We have the above scenario almost exactly. .NET 4.7.1 top level projects (exe's, Web App's) calling into a mix of .NET 4.7.1 and .NET Standard 2.0 assemblies that make use of You can see a chronicle of my journey in trying to resolve it here: simpleinjector/SimpleInjector#508. I don't at all like the workaround that I ended up with, which was using The version of File Version; 4.6.25908.2 When the workaround described above is applied, we end up with Version 4.6.24605.1 of System.Net.Http in our bin folders and everything works fine. |
So on VS 15.5.6 the right System.Net.Http will be copied to the output directory, the problem is that the tooling won't automatically add a binding redirect for you to it until VS 15.6 comes out. I'm sorry that you have to workaround this for now, but once we release 15.6 you should be able to remove that p roperty and remove the binding redirects since they will be calculated for you only for the ones that you actually need. |
@joperezr Thank you for that confirmation. Glad it will be fixed soon and that I didn't do something wrong. |
Sorry for the trouble, and we will keep you posted once the fix comes out. |
I have VS 2017 15.5.5 and 15.5.6, and this issue is still there. Ah, apologize. I have missed the previous comment above. |
@joperezr I just installed the release version of 15.6 and the problem persists in .NET framework projects calling into .NET Standard projects with HttpClients crossing boundaries. I've removed the |
@mscrivo Yes, I'm so sorry for the trouble. Because of some internal problems, the fix went in but it was too late to make it for VS 15.6. I have checked the preview build of 15.7 preview 2 and that one does contain the fix. We are actually in talks right now to try to get this specific issue serviced to 15.6.1 but is not yet clear if we will able to do it or not. Again, I'm so sorry for the trouble you are hitting, and we will work hard to get the fix to you ASAP. |
Thanks @joperezr |
@joperezr I just tried 15.7 Preview 2 just to make sure it's actually fixed, and it doesn't seem to be. I get the same behavior, System.ExecutionEngineException on System.Net.Http related code. |
We actually did get the fix in to 15.6.3 (which we already shipped), so if you install the latest RTM product this should be there. Do you see the file |
@joperezr I do have that file in both my 15.7 Preview folder and 15.6.4 folder. Interesting! I will try to get you a build log and a minimal repro solution. Is there someway less public that I can send you a build log and perhaps a memory dump from IIS? |
@joperezr I created a sample app that repro's the issue somewhat: https://github.com/mscrivo/System.Net.Http.Crash I say somewhat, because it seems the root cause is the same, but in our real app, we end up with a crash instead, but anyhow, I think this should be sufficient to show the problem. The app at this repo consists of a .NET Standard 2.0 lib that has a generic API client which uses
on the following line: |
The sample solution does in fact repro the |
ok, thanks for the repro I'll take a look at it today. |
Thank you |
@mscrivo I see what's going on. Apparently, this seems to be a known issue we have I just don't know if we actually have an issue on GitHub for it. The problem is with our tooling and it is specific to ASP.NET Web Applications. First of all, because of the way they are built, automatic binding redirects generation is currently broken. That basically forces you to do what you already did, which is to double-click the warning in VS in order to add those to your Web.config. Secondly, once the app runs in IIS, the extra dlls that we add to your bin directory won't get copied over, so that will make the app fail at runtime since it won't be able to find System.Net.Http 4.2.0.0 version. A tooling team is currently working on fixing both of these issues but unfortunately, we don't have an ETA for it yet. @terrajobst are there any known workarounds for this issue? For example, some target that will deploy the extra runtime facades into the IIS folder? |
Thanks @joperezr .. I'm frankly surprised more people haven't run into this. A better workaround would be nice as our current one leads to many build warnings regarding the System.Net.Http binding redirects being wrong (since we are forcing 4.0), and intellisense broken in VS whenever it comes to code that deals with HttpClient. |
I totally agree with you. I'll make sure to push for a fix ASAP from our tooling side. |
We are running into the same issues. I am having to copy the shim dlls and include them into our source control and manually set a reference and tell it to copy, until a fix is in place. This has been very frustrating, especially when we have deadlines to deliver business value to our end customers. |
I don’t understand why you just couldnt have kept the version number the same as the framework, the public key was left the same. This reminds me of the days of COM and DLL hell. |
Was the issue mentioned here #1712 (comment) ever resolved? Still running into this with VS2017 15.7.3 and an ASP .NET targeting 4.7.1. |
I don't believe there is a tooling fix for that yet, but we fixed the underlining issue requiring those extra shims so that if you now target .NET Framework 4.7.2 you shouldn't see this issues any longer. |
@joperezr Thanks for the speedy response! Sounds good, I'll retarget for 4.7.2. |
I have tested the 15.8.0, using .NET Framework 4.7.2 as the target. It is fixed! 👍 |
…902.1 (#1712) [main] Update dependencies from dotnet/arcade
cc: @AlexGhiondea @weshaggard @dsplaisted @livarcocc
These are the required changes for copying the required shims in order to run a net471 app that contains assets that were built using the support package. An example of a case that is currently broken is the following:
The reason behind it is that since the net461 library depends on a NS1.5+ library, it will be built against the shims contained in the support package. These shims, have in some cases a higher assembly version than the one we have inbox on net471 (in 12 cases as I mentioned above). That means that your net461 library, will depend on a higher assembly version of a library than the ones present inbox on net471, which will cause a missing assembly error.