如何诊断dnx中缺少依赖项(或其他加载程序故障)? [英] How can I diagnose missing dependencies (or other loader failures) in dnx?

查看:78
本文介绍了如何诊断dnx中缺少依赖项(或其他加载程序故障)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试运行 HelloWeb示例的修改版本使用Kestrel在DNX上使用ASP.NET vNext.我知道这非常非常,但是我希望ASP.NET团队至少能够保持最简单的Web应用程序正常工作:)

I'm trying to run a modified version of the HelloWeb sample for ASP.NET vNext on DNX using Kestrel. I understand that this is very much on the bleeding edge, but I would hope that the ASP.NET team would at least keep the simplest possible web app working :)

环境:

  • Linux(Ubuntu,差不多)
  • Mono 3.12.1
  • DNX 1.0.0-beta4-11257(我也有11249个可用)

"Web应用"代码,在Startup.cs中:

"Web app" code, in Startup.cs:

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

项目配置,在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似乎可以正常工作.

但是,当我尝试运行时,出现异常提示找不到Microsoft.Framework.Runtime.IApplicationEnvironment.命令行和错误(已重新格式化)

When I try to run, however, I get an exception suggesting that Microsoft.Framework.Runtime.IApplicationEnvironment can't be found. Command line and error (somewhat reformatted)

.../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

很明显,我最迫切的需要是解决此问题,同时,我也非常感谢您提供有关如何逐步诊断出问题的建议,以便将来自己解决类似的问题. (这也可能使这个问题对其他人也更有用.)

While obviously, my most pressing need is to fix this, I'd also appreciate advice on how to move to diagnose what's going wrong so I can fix similar issues myself in the future. (That's also likely to make this question more useful to others, too.)

我在组装中立接口,但无法从错误中清除.( [AssemblyNeutral]已经死了,不是吗... )

I've found Microsoft.Framework.Runtime.IApplicationEnvironment in the Microsoft.Framework.Runtime.Interfaces assembly source, and that doesn't appear to have changed recently. It's not clear why the exception shows the name as if it's a whole assembly in itself, rather than just an interface within another assembly. I'm guessing this may be due to assembly neutral interfaces, but it's not clear from the error. ([AssemblyNeutral] is dead, so that's not it...)

推荐答案

好问题.对于您的特定问题,看来您解决的依赖项不匹配.当发生这种情况时,可能是因为您在不兼容的dnx上运行您的应用程序.我们仍在进行重大更改,因此,如果您发现缺少缺少类型的方法,则很可能最终运行了betaX软件包和betaY dnx,反之亦然.

Good question. For your specific problem, it looks like you have a mismatch in your resolved dependencies. When things like this happen it's likely because you're running your application on an incompatible dnx. We're still making very big breaking changes so if you ever see method missing of type missing, chances are you ended up running betaX packages and betaY dnx or vice versa.

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

Even more specifically, Assembly Neutral Interfaces were removed in beta4 but it looks like the application you are running is still using them.

我们有计划这样做,以便程序包可以标记它们运行所需的最小dnx,以使错误消息更加清晰.随着时间的流逝,重大的变化也将消失.

We have plans to make it so that packages can mark the minimum dnx that they require to run to make the error message more clear. Also as time goes by, the breaking changes will die down.

尽管如此,总的来说,我觉得是时候我写了一篇指南,介绍如何在使用dnx时诊断此类问题(因为它与现有的.NET完全不同).

In general though, I feel like it's time I wrote a guide on how to diagnose issues like this when using the dnx (since it's pretty different to existing .NET).

您放入project.json的依赖项仅是顶级的.版本也是始终最低(就像NuGet软件包一样).这意味着当您指定Foo 1.0.0-beta4时,您实际上是在指定Foo >= 1.0.0-beta4.这意味着,如果您要求输入MVC 0.0.1,并且配置的供稿上的最低版本是MVC 3.0.0,则将得到该版本.除非您指定,否则我们也从不浮动您的版本.如果要求1.0.0并且存在,那么即使存在较新的版本,也将获得1.0.0.指定空版本总是错误的,并且在以后的版本中是不允许的.

Dependencies you put into project.json are top level only. Versions are also always minimums (it's just like a NuGet package). This means that when you specify Foo 1.0.0-beta4 you're really specifying Foo >= 1.0.0-beta4. This means if you ask for MVC 0.0.1 and the minimum versions on your configured feed is MVC 3.0.0, you'll get that one. We also NEVER float your version unless you specify it. If you ask for 1.0.0 and it exists, you will get 1.0.0 even if newer versions exist. Specifying empty versions is ALWAYS bad and will be disallowed in later builds.

我们要为nuget引入一个新功能,称为浮动版本.今天,它仅适用于prerelease标签,但在下一版本中,它将适用于该版本的更多部分.这类似于npm和gem语法,用于在程序包规范文件中指定版本范围.

There's a new feature we're introducing to nuget called floating versions. Today it only works on the prerelease tag, but in the next version it'll work on more parts of the version. This is similar to npm and gem syntax for specifying version ranges in the package specification file.

1.0.0-*-表示给我匹配前缀的最高版本(根据语义版本控制规则),或者如果没有与之匹配的版本前缀,请使用正常行为,并获取最低版本> =指定版本.

1.0.0-* - Means give me the HIGHEST version matching the prefix (according to semantic versioning rules) OR if there is no version matching that prefix, use normal behavior and get me the LOWEST version >= the specified version.

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

When you run restore in the latest builds, it will write out a file called project.lock.json. This file will have the transitive closure of dependencies for all target frameworks defined in project.json.

当此类操作失败时,您可以执行以下操作:

When something like this fails you can do the following:

使用kpm list查看已解决的依赖性.这将向您显示项目引用的软件包的已解析版本以及将其引入的依赖项.如果是A-> B,则会显示:

Take a look at the resolved dependencies using kpm list. This will show you the resolved versions of packages referenced by your project and what dependency pulled it in. e.g. if A -> B, it'll show:


A
  -> B
B
 ->

实际KPM列表输出:

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

Listing dependencies for 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

*表示直接依赖.

如果您有一个正在运行的Visual Studio(目前已与DNX分离),则可以查看引用"节点.它具有以视觉方式表示的相同数据:

If you have a working visual studio (which breaks with DNX right now), you can look at the references node. It has the same data represented visually:

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

Let's look at what a dependency failure looks like:

这是project.json

Here's the 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 restore将显示以下内容:

Newtonsoft.Json 8.0.0 doesn't exist. So running kpm restore shows the following:

当诊断还原何时可能失败时,请查看发出的HTTP请求,它们会告诉您kpm查找了哪些已配置的软件包源.请注意,在上图中,有一个CACHE请求.这是基于资源类型(nupkg或nuspec)的内置缓存,并且具有可配置的TTL(请参见kpm restore --help).如果要强制kpm击中远程NuGet源,请使用--no-cache标志:

When diagnosing when restore might have failed, look at the HTTP requests made, they tell you what configured package sources kpm looked in. Notice in the above image, there is a CACHE request. This is the built in caching based on the type of resource (nupkg or nuspec) and has a configurable TTL (look at kpm restore --help). If you want to force kpm to hit the remote NuGet sources, use the --no-cache flag:

这些错误也会显示在Visual Studio的程序包管理器"日志输出窗口中:

These errors also show up in Visual Studio in the package manager log output window:

旁注!

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

I'll describe the way NuGet.config works right now (which will likely change in the future). By default you have a NuGet.config with the default NuGet.org source configured globally in %appdata%\NuGet\NuGet.Config. You can manage these global sources within visual studio or with the NuGet command line tool. You should always look at your effective sources (the ones listed in the kpm output) when trying to diagnose failures.

此处

回到现实:

当未解决依赖项时,运行应用程序将为您提供:

When dependencies are unresolved, running the application will give you this:

> 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)

运行时基本上会在尝试运行之前尝试验证是否已解决整个依赖关系图.如果它建议运行kpm restore,则是因为它找不到列出的依赖项.

The runtime basically tries to validate that the entire dependency graph is resolved before attempting to run. If it suggests running kpm restore it's because it can't find the dependencies listed.

您可能会收到此错误的另一个原因是,如果您运行的是错误的dnx风格.如果您的应用程序仅指定dnx451,并且您尝试运行CoreCLR dnx,则可能会遇到类似的问题.密切注意错误消息中的目标框架:

Another reason why you might get this error is if you're running the wrong dnx flavor. If your application only specifies dnx451 and you try to run the CoreCLR dnx, you might see a similar problem. Pay close attention to the target framework in the error message:

运行:

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

当您尝试运行时,您应该记住从clr到您的project.json中定义的目标框架的思维导图.

When you're trying to run, you should remember that mental mapping from clr to target framework defined in your project.json.

这也显示在Visual Studio的引用"节点下:

This also shows up in Visual Studio under the references node:

标记为黄色的节点尚未解析.

The nodes marked as yellow are unresolved.

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

These also show up in the error list:

在构建时也会出现这些错误.从命令行构建时,输出非常冗长,在诊断问题时可能非常有用:

These errors also show up when building. When building from the command line, the output is very verbose and can be extremely useful when diagnosing problems:

> 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

输出显示了从程序包和项目引用传递到编译器的所有程序集.当您开始遇到构建失败的问题时,查看此处以确保您使用的软件包在该目标平台上确实有效是很有用的.

The output shows all of the assemblies passed into the compiler from packages and project references. When you start getting build failures, it's useful to look here to make sure that the package you are using actually works on that target platform.

这是在dnxcore50上不起作用的软件包的示例:

Here's an example of a package that doesn't work on 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 version 3.0.0 does not have any assemblies that run on dnxcore50 (take a look at the unzipped package's lib folder). When we run kpm build:

注意它说正在使用包Microsoft.Owin.Host.SystemWeb",但没有文件:".这可能是构建失败的原因.

Notice it says "using Package Microsoft.Owin.Host.SystemWeb" but there is not "File:". This could be the reason for a build failure.

到此我的脑筋急转弯

这篇关于如何诊断dnx中缺少依赖项(或其他加载程序故障)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆