我如何诊断在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
标志:
这些错误也出现在包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
:
注意它说“使用包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_TRACE
为1
以查看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 . web
或dnx . 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" ] }