我如何诊断在dnx中缺less的依赖关系(或其他加载失败)?

我正在尝试使用Kestrel在DNX上为ASP.NET vNext运行HelloWeb示例的修改版本。 我明白,这是非常stream行的边缘,但我希望ASP.NET团队至less保持最简单的可能的Web应用程序工作:)

环境:

  • Linux(Ubuntu,非常多)
  • 单声道3.12.1
  • DNX 1.0.0-beta4-11257(我也有11249)

Startup.cs “Web应用程序”代码:

 using Microsoft.AspNet.Builder; public class Startup { public void Configure(IApplicationBuilder app) { app.UseWelcomePage(); } } 

项目configuration,在project.json

 { "dependencies": { "Kestrel": "1.0.0-beta4", "Microsoft.AspNet.Diagnostics": "1.0.0-beta4", "Microsoft.AspNet.Hosting": "1.0.0-beta4", "Microsoft.AspNet.Server.WebListener": "1.0.0-beta4", "Microsoft.AspNet.StaticFiles": "1.0.0-beta4", "Microsoft.Framework.Runtime": "1.0.0-beta4", "Microsoft.Framework.Runtime.Common": "1.0.0-beta4", "Microsoft.Framework.Runtime.Loader": "1.0.0-beta4", "Microsoft.Framework.Runtime.Interfaces": "1.0.0-beta4", }, "commands": { "kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:5004" }, "frameworks": { "dnx451": {} } } 

kpm restore似乎正常工作。

当我尝试运行时,但是,我收到一个exception,提示无法findMicrosoft.Framework.Runtime.IApplicationEnvironment 。 命令行和错误(有些重新格式化)

 .../HelloWeb$ dnx . kestrel System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Framework.Runtime.IApplicationEnvironment, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. File name: 'Microsoft.Framework.Runtime.IApplicationEnvironment, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&) at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0 

虽然显然我最迫切的需要是解决这个问题,但是我也希望能提出一些build议,帮助我们诊断出现问题的方法,以便我可以在将来解决类似的问题。 (这也可能使这个问题对其他人更有用。)

我在Microsoft.Framework.Runtime.Interfaces程序集源代码中find了Microsoft.Framework.Runtime.Interfaces ,而且最近似乎没有更改。 目前还不清楚为什么这个exception显示这个名字就好像它本身就是一个完整的程序集,而不仅仅是另一个程序集中的一个接口。 我猜这可能是由于汇编中性接口 ,但从错误不清楚。[AssemblyNeutral]死了,所以不是… )

好问题。 对于你的具体问题,看起来你已经解决了依赖关系的不匹配问题。 当这样的事情发生时,可能是因为你正在一个不兼容的dnx上运行你的应用程序。 我们仍然在做出非常大的突破性改变,所以如果你看到丢失types的方法,你可能会运行betaX包和betaY dnx,反之亦然。

更具体地说, 组装中立接口在beta4中被删除了,但是看起来你正在运行的应用程序仍在使用它们。

我们已经制定了这样的计划,使软件包可以标记他们需要运行的最小dnx,使错误信息更加清晰。 随着时间的推移,突破的变化将会消失。

一般来说,我觉得现在是时候编写一个关于如何在使用dnx时诊断问题的指南(因为它与现有的.NET很不相同)。

您放入project.json依赖关系只是顶级的。 版本也总是最低限度 (这就像一个NuGet包)。 这意味着当您指定Foo 1.0.0-beta4您确实指定了Foo >= 1.0.0-beta4 。 这意味着如果您要求MVC 0.0.1并且您configuration的提要上的最低版本是MVC 3.0.0 ,那么您将获得该版本。 除非你指定它,否则我们也不会浮动你的版本。 如果您要求1.0.0并且存在,即使存在更新的版本,也会得到1.0.0。 指定空的版本总是不好的,并将在以后的版本中被禁止。

我们向nuget介绍的一个新function称为浮动版本。 今天它只适用于预发行标签,但在下一个版本中,它将在更多版本的部分工作。 这与在包规范文件中指定版本范围的npm和gem语法类似。

1.0.0-* – 手段给我匹配前缀的最高版本(根据语义版本规则 ),或者如果没有匹配那个前缀的版本,使用正常的行为并且得到我最低版本> =指定的版本。

在最新版本中运行还原时,它会写出一个名为project.lock.json的文件。 这个文件将具有在project.json定义的所有目标框架的依赖关系的传递闭包。

当这样的事情失败时,你可以做到以下几点:

使用kpm list查看已解决的依赖关系。 这将显示你的项目引用的软件包的parsing版本和什么依赖拉入它。例如,如果A – > B,它会显示:

一个
   - > B
乙
  - >

实际的KPM列表输出:

列出ClassLibrary39的依赖关系(C:\ Users \ davifowl \ Documents \ Visual Studio 14 \ Projects \ ClassLibrary39 \ src \ ClassLibrary39 \ project.json)

 [Target framework DNX,Version=v4.5.1 (dnx451)] framework/Microsoft.CSharp 4.0.0.0 -> ClassLibrary39 1.0.0 framework/mscorlib 4.0.0.0 -> ClassLibrary39 1.0.0 framework/System 4.0.0.0 -> ClassLibrary39 1.0.0 framework/System.Core 4.0.0.0 -> ClassLibrary39 1.0.0 *Newtonsoft.Json 6.0.1 -> ClassLibrary39 1.0.0 [Target framework DNXCore,Version=v5.0 (dnxcore50)] *Newtonsoft.Json 6.0.1 -> ClassLibrary39 1.0.0 System.Runtime 4.0.20-beta-22709 -> ClassLibrary39 1.0.0 

*表示直接依赖。

如果你有一个工作的视觉工作室(现在打破DNX),你可以看看参考节点。 它具有相同的可视化数据:

参考节点

让我们看看依赖性失败的样子:

这是project.json

 { "version": "1.0.0-*", "dependencies": { "Newtonsoft.Json": "8.0.0" }, "frameworks" : { "dnx451" : { "dependencies": { } }, "dnxcore50" : { "dependencies": { "System.Runtime": "4.0.20-beta-22709" } } } } 

Newtonsoft.Json 8.0.0不存在。 所以运行kpm恢复显示如下:

在这里输入图像说明

在诊断何时恢复可能失败时,请查看所做的HTTP请求,它们会告诉您configuration的包源kpm查看了哪些内容。请注意,上图中有一个CACHE请求。 这是基于资源types(nupkg或nuspec)的内置caching,并具有可configuration的TTL(查看kpm restore --help )。 如果你想强制kpm命中远程的NuGet源,使用--no-cache标志:

KPM恢复 - 无缓存

这些错误也出现在包pipe理器日志输出窗口中的Visual Studio中:

在这里输入图像说明

边注!

包来源

我将描述NuGet.config现在的工作方式(将来可能会改变)。 默认情况下,您有一个NuGet.config,其中包含在%appdata%\NuGet\NuGet.Config全局configuration的默认NuGet.org源代码。 您可以在Visual Studio或NuGet命令行工具中pipe理这些全局资源。 尝试诊断故障时,应始终查看有效的来源(kpm输出中列出的来源)。

阅读更多关于NuGet.config的信息

回到现实:

当依赖没有解决时,运行应用程序会给你这个:

 > dnx . run System.InvalidOperationException: Failed to resolve the following dependencies for target framework 'DNX,Version=v4.5.1': Newtonsoft.Json 8.0.0 Searched Locations: C:\Users\davifowl\Documents\Visual Studio 14\Projects\ClassLibrary39\src\{name}\project.json C:\Users\davifowl\Documents\Visual Studio 14\Projects\ClassLibrary39\test\{name}\project.json C:\Users\davifowl\.dnx\packages\{name}\{version}\{name}.nuspec C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\{name}.dll C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\Facades\{name}.dll C:\WINDOWS\Microsoft.NET\assembly\GAC_32\{name}\{version}\{name}.dll C:\WINDOWS\Microsoft.NET\assembly\GAC_64\{name}\{version}\{name}.dll C:\WINDOWS\Microsoft.NET\assembly\GAC_MSIL\{name}\{version}\{name}.dll Try running 'kpm restore'. at Microsoft.Framework.Runtime.DefaultHost.GetEntryPoint(String applicationName) at Microsoft.Framework.ApplicationHost.Program.ExecuteMain(DefaultHost host, String applicationName, String[] args) at Microsoft.Framework.ApplicationHost.Program.Main(String[] args) 

运行时基本上试图validation整个依赖关系图在尝试运行之前已经解决。 如果它build议运行kpm restore它是因为它找不到列出的依赖项。

你可能会得到这个错误的另一个原因是如果你运行了错误的DNX风格。 如果您的应用程序只指定了dnx451,而您尝试运行CoreCLR dnx,则可能会看到类似的问题。 密切关注错误信息中的目标框架:

运行:

 dnx4x - runs on dnx-clr-{etc} dnxcore50 - runs on dnx-coreclr-{etc} 

当你试图运行的时候,你应该记住从你的project.json定义的从clr到目标框架的心理映射。

这也显示在Visual Studio下的引用节点下: 未解决的依赖关系

标记为黄色的节点未解决。

这些也显示在错误列表中:

错误列表未解决的依赖关系

build造

这些错误也显示出来时,build设。 从命令行构build时,输出非常冗长,在诊断问题时非常有用:

 > kpm build Building ClassLibrary39 for DNX,Version=v4.5.1 Using Project dependency ClassLibrary39 1.0.0 Source: C:\Users\davifowl\Documents\Visual Studio 14\Projects\ClassLibrary39\src\ClassLibrary39\project.json Using Assembly dependency framework/mscorlib 4.0.0.0 Source: C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\mscorlib.dll Using Assembly dependency framework/System 4.0.0.0 Source: C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.dll Using Assembly dependency framework/System.Core 4.0.0.0 Source: C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Core.dll Using Assembly dependency framework/Microsoft.CSharp 4.0.0.0 Source: C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\Microsoft.CSharp.dll Building ClassLibrary39 for DNXCore,Version=v5.0 Using Project dependency ClassLibrary39 1.0.0 Source: C:\Users\davifowl\Documents\Visual Studio 14\Projects\ClassLibrary39\src\ClassLibrary39\project.json Using Package dependency System.Console 4.0.0-beta-22709 Source: C:\Users\davifowl\.dnx\packages\System.Console\4.0.0-beta-22709 File: lib\contract\System.Console.dll Using Package dependency System.IO 4.0.10-beta-22231 Source: C:\Users\davifowl\.dnx\packages\System.IO\4.0.10-beta-22231 File: lib\contract\System.IO.dll Using Package dependency System.Runtime 4.0.20-beta-22231 Source: C:\Users\davifowl\.dnx\packages\System.Runtime\4.0.20-beta-22231 File: lib\contract\System.Runtime.dll Using Package dependency System.Text.Encoding 4.0.10-beta-22231 Source: C:\Users\davifowl\.dnx\packages\System.Text.Encoding\4.0.10-beta-22231 File: lib\contract\System.Text.Encoding.dll Using Package dependency System.Threading.Tasks 4.0.10-beta-22231 Source: C:\Users\davifowl\.dnx\packages\System.Threading.Tasks\4.0.10-beta-22231 File: lib\contract\System.Threading.Tasks.dll 

输出显示了所有从程序包和项目引用传入编译器的程序集。 当你开始出现构build失败的时候,在这里寻找确保你使用的包实际上在这个目标平台上工作是有用的。

下面是一个在dnxcore50上不起作用的例子:

 { "version": "1.0.0-*", "dependencies": { "Microsoft.Owin.Host.SystemWeb": "3.0.0" }, "frameworks": { "dnx451": { "dependencies": { } }, "dnxcore50": { "dependencies": { "System.Console": "4.0.0-beta-22709" } } } } 

Microsoft.Owin.Host.SystemWeb版本3.0.0没有任何在dnxcore50上运行的程序集(查看解压缩的程序包的lib文件夹)。 当我们运行kpm build

缺少dnxcore50上的程序集

注意它说“使用包Microsoft.Owin.Host.SystemWeb”,但没有“文件:”。 这可能是构build失败的原因。

这里结束了我的大脑转储

我仍然不完全知道什么是错误的,但是我现在有一系列的步骤,至less让事情变得更容易:

  • 如有疑问,请重新安装dnx
    • 吹走软件包caching可能会有帮助
  • 检查~/.config/NuGet.config以确保您使用的是正确的NuGet提要

我结束了使用下面的命令行以合理的干净的方式testing各种选项:

 rm -rf ~/.dnx/packages && rm -rf ~/.dnx/runtimes && dnvm upgrade && kpm restore && dnx . kestrel 

它看起来像我的问题是由于正在安装的依赖关系的错误版本。 "1.0.0-beta4-*"的版本号显然与"1.0.0-beta4-*"完全不同。 例如,刚刚指定为1.0.0-beta4的Kestrel依赖项安装了1.0.0-beta4-11185版本,而1.0.0-beta4-11262版本的末尾是-* 。 我想明确指定beta4以避免意外地使用beta3版本

下面的项目configuration工作正常:

 { "dependencies": { "Kestrel": "1.0.0-beta4-*", "Microsoft.AspNet.Diagnostics": "1.0.0-beta4-*", "Microsoft.AspNet.Hosting": "1.0.0-beta4-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-beta4-*", }, "commands": { "kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:5004" }, "frameworks": { "dnx451": {} } } 

您可以将名为DNX_TRACE的env DNX_TRACE1以查看TON更多的诊断信息。 被警告,这是更多的信息!

为了得到它的工作,我修改了我的project.json ..现在看起来像:

 { "dependencies": { "Kestrel": "1.0.0-*", "Microsoft.AspNet.Diagnostics": "1.0.0-*", "Microsoft.AspNet.Hosting": "1.0.0-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-*", "Microsoft.AspNet.StaticFiles": "1.0.0-*" }, "commands": { "web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5001", "kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:5004" }, "frameworks": { } } 

关键似乎是框架部分。

此外重命名改变了如何k web作品,使其现在的dnx . web dnx . webdnx . kestrel dnx . kestrel

更新 – 位更多信息

奇怪的是,在没有定义框架的情况下运行后,当我做了kpm restore时,它得到了一堆额外的东西:

 ... Installing Microsoft.Framework.Logging 1.0.0-beta4-11001 Installing Microsoft.Framework.Logging.Interfaces 1.0.0-beta4-11001 Installing Microsoft.Framework.DependencyInjection.Interfaces 1.0.0-beta4-11010 Installing Microsoft.Framework.DependencyInjection 1.0.0-beta4-11010 Installing Microsoft.Framework.ConfigurationModel 1.0.0-beta4-10976 Installing Microsoft.Framework.ConfigurationModel.Interfaces 1.0.0-beta4-10976 Installing Microsoft.AspNet.Hosting.Interfaces 1.0.0-beta4-11328 Installing Microsoft.AspNet.FeatureModel 1.0.0-beta4-11104 Installing Microsoft.AspNet.Http 1.0.0-beta4-11104 Installing Microsoft.AspNet.FileProviders.Interfaces 1.0.0-beta4-11006 Installing Microsoft.Framework.Caching.Interfaces 1.0.0-beta4-10981 Installing Microsoft.AspNet.FileProviders 1.0.0-beta4-11006 Installing Microsoft.AspNet.Http.Core 1.0.0-beta4-11104 Installing Microsoft.AspNet.WebUtilities 1.0.0-beta4-11104 Installing Microsoft.Net.Http.Headers 1.0.0-beta4-11104 Installing Microsoft.AspNet.Http.Interfaces 1.0.0-beta4-11104 Installing Microsoft.Framework.Runtime.Interfaces 1.0.0-beta4-11257 Installing Microsoft.AspNet.Server.Kestrel 1.0.0-beta4-11262 Installing Microsoft.Net.Http.Server 1.0.0-beta4-11698 Installing Microsoft.Net.WebSockets 1.0.0-beta4-11698 Installing Microsoft.Net.WebSocketAbstractions 1.0.0-beta4-10915 Installing Microsoft.Framework.WebEncoders 1.0.0-beta4-11104 Installing Microsoft.Framework.OptionsModel 1.0.0-beta4-10984 Installing Microsoft.AspNet.Http.Extensions 1.0.0-beta4-11104 Installing Microsoft.AspNet.Diagnostics.Interfaces 1.0.0-beta4-12451 Installing Microsoft.AspNet.RequestContainer 1.0.0-beta4-11328 

然后它运行良好。 然后我切换回框架部分

 "frameworks": { "dnx451": {} } 

..它仍然工作,而之前它会抛出一个错误!

很奇怪!

(我正在运行1.0.0-beta4-11257

进一步更新

我创build了一个新的Ubuntu实例,并得到了与你一样的错误..我的想法是,这个问题可能是由于它只试图从nuget.org而不是myget.org (它有更新的东西)我把一个NuGet.Config放入项目的根目录

 <?xml version="1.0" encoding="utf-8"?> <configuration> <packageSources> <add key="AspNetVNext" value="https://www.myget.org/F/aspnetvnext/" /> <add key="NuGet" value="https://nuget.org/api/v2/" /> </packageSources> </configuration> 

..这似乎已经通过获得正确的版本(另一个kpm restore )已经修复了它。

现在,我所有的package.json版本都以"-rc2-*"结尾

(目前为止,我所见过的例外情况是Microsoft.Framework.Configuration包,它们需要是"1.0.0-rc1-*""1.0.0-*"

关于@davidfowl提到的“版本列表”,beta8和rc2之间似乎已经消失了很多痛苦。

 dnvm upgrade -u -arch x64 -r coreclr 

我已经有了coreclr与这两个NuGet饲料最幸运的:

 "https://www.myget.org/F/aspnetvnext/" "https://nuget.org/api/v2/" 

当我确实缺less包装问题时,90%的时间都是这些相同的元凶:

 Newtonsoft.Json Ix-Async Remotion.Linq 

大多数情况下,我可以通过强制NuGet.org的主要源来解决这些问题:

 dnu restore; dnu restore -s https://nuget.org/api/v2 

这是我的工作config.json:

 { "dependencies": { "Microsoft.AspNet.Diagnostics": "1.0.0-rc2-*", "Microsoft.AspNet.Diagnostics.Entity": "7.0.0-rc2-*", "Microsoft.AspNet.Hosting": "1.0.0-rc2-*", "Microsoft.AspNet.Http": "1.0.0-rc2-*", "Microsoft.AspNet.Http.Abstractions": "1.0.0-rc2-*", "Microsoft.AspNet.Mvc.Core": "6.0.0-rc2-*", "Microsoft.AspNet.Mvc.Razor": "6.0.0-rc2-*", "Microsoft.AspNet.Owin": "1.0.0-rc2-*", "Microsoft.AspNet.Routing": "1.0.0-rc2-*", "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc2-*", "Microsoft.AspNet.Server.WebListener": "1.0.0-rc2-*", "Microsoft.AspNet.Session": "1.0.0-rc2-*", "Microsoft.AspNet.StaticFiles": "1.0.0-rc2-*", "EntityFramework.Commands": "7.0.0-rc2-*", "EntityFramework.Core": "7.0.0-rc2-*", "EntityFramework.InMemory": "7.0.0-rc2-*", "EntityFramework.MicrosoftSqlServer": "7.0.0-rc2-*", "EntityFramework.MicrosoftSqlServer.Design": "7.0.0-rc2-*", "EntityFramework.Relational": "7.0.0-rc2-*", "EntityFramework7.Npgsql": "3.1.0-beta8-2", "Microsoft.Extensions.Logging.Abstractions": "1.0.0-rc2-*", "Microsoft.Extensions.Logging.Console": "1.0.0-rc2-*", "Microsoft.Extensions.DependencyInjection": "1.0.0-rc2-*", "Microsoft.Extensions.DependencyInjection.Abstractions": "1.0.0-rc2-*", "Microsoft.Framework.Configuration.CommandLine": "1.0.0-*", "Microsoft.Framework.Configuration.EnvironmentVariables": "1.0.0-*", "Microsoft.Framework.Configuration.Json": "1.0.0-*" }, "commands": { "ef": "EntityFramework.Commands", "dev": "Microsoft.AspNet.Hosting --ASPNET_ENV Development --server Microsoft.AspNet.Server.Kestrel --server.urls http://localhost:5004" }, "frameworks": { "dnxcore50": {} } } 

我试图安抚dnxcore50和dnx451引用,并且依赖性丢失了。

如果我理解这个框架之间的“依赖关系”:{}是共享的。

然后,“框架”内的“依赖关系”:{}是特定于该框架的。

dnxcore50是一个模块化的运行时(自包含的),所以它基本上包含了所有的核心运行时需要运行一个程序,而不像传统的.net框架,其中你的核心依赖散落​​在其他地方。

所以说,我想坚持最小的方法,我决定在某些时候在Mac或Linux上托pipe。

使用cshtml视图将Ran 更新为奇怪的依赖项问题,现在只需要使用dnx451。

这是我的project.json

 { "webroot": "wwwroot", "version": "1.0.0-*", "dependencies": { "System.Runtime": "4.0.10", "Microsoft.AspNet.Hosting": "1.0.0-beta4", "Microsoft.AspNet.Mvc": "6.0.0-beta4", "Microsoft.AspNet.Server.IIS": "1.0.0-beta6-12075", "Microsoft.AspNet.Server.WebListener": "1.0.0-beta6-12457", "Microsoft.Framework.DependencyInjection": "1.0.0-beta4", "Microsoft.Framework.DependencyInjection.Interfaces": "1.0.0-beta5" }, "commands": { "web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://admin.heartlegacylocal.com" }, "frameworks": { "dnx451": { } } }, "publishExclude": [ "node_modules", "bower_components", "**.xproj", "**.user", "**.vspscc" ], "exclude": [ "wwwroot", "node_modules", "bower_components" ] }