-
Notifications
You must be signed in to change notification settings - Fork 2.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
Initializing Orleans client in an Asp.net RC2 Core (.Net Framework) project logs the following exception on startup #1840
Comments
Not sure what's going on but it looks like some component is trying to load libuv.dll (a native component) via reflection only load. I assume this is just a first chance exception? |
Yes, the Orleans client functions correctly following initialization despite these errors. |
On startup, the Orleans client searches for grain interfaces using reflection. That's normal behavior. Sometimes a DLL load may fail, in these cases the error is logged. |
We are looking to add an option to avoid blind scanning of binaries, but this is the current 'by design' behavior. |
Ok thanks. It would definitely be nice to have some hooks to control the assembly scan. |
@globeport Feel free to suggest what the hooks should look like. |
With the code-based configuration, could it just be a delegate? Say, var config = new ClusterConfiguration();
config.Defaults.AssemblyListProvider = () => {
return new List<string>()
{
"C:/Foo/bar.dll"
};
}; Not sure how this works out with xml-based configurations... |
I think we can solve this by smartening the loader by checking the PE Header in the binaries using Kirill Osenkov's answer here at SO: http://stackoverflow.com/questions/367761/how-to-determine-whether-a-dll-is-a-managed-assembly-or-native-prevent-loading Which points to: http://apichange.codeplex.com/SourceControl/changeset/view/76c98b8c7311#ApiChange.Api/src/Introspection/CorFlagsReader.cs What do you think? |
@TrexinanF14 I'm concerned full paths may be a problem, especially in case Azure Cloud Services. Why not just assembly names? @attilah It would really help indeed to auto-skip non-managed dlls. |
@sergeybykov Yeah, scratch the full path requirement, although it seems that accepting relative paths would be a good idea (relative based on the location of the executing assembly?). Or some other method to look outside the default directories. Should this conversation hop over to #1852? It seems like the solution provided by @attilah would solve this issue. |
Based on the CorFlagsReader above I wrote this snippet and tested on major windows directories on my system, seems to work ok. What was got to assembly loading that was loaded properly! try
{
var flags = default(CorFlagsReader);
// Use stream to have least access required for Assembly loading
using (var stream = File.Open(filename, FileMode.Open, FileAccess.Read))
{
flags = CorFlagsReader.ReadAssemblyMetadata(stream);
}
if (flags != null)
{
var isManaged = flags.IsPureIL || flags.ProcessorArchitecture == ProcessorArchitecture.MSIL;
var isProcessorArchitectureMatching =
(Environment.Is64BitProcess && flags.ProcessorArchitecture == ProcessorArchitecture.Amd64) ||
(!Environment.Is64BitProcess && flags.ProcessorArchitecture == ProcessorArchitecture.X86);
if (isManaged && isProcessorArchitectureMatching)
{
// At this point the file is "safe" to load
// user specific predicate can be called here if we'd like to support blacklisting too.
}
}
}
catch (IOException)
{
}
catch (UnauthorizedAccessException)
{
} BadImageFormatException is not needed to check here, since no assembly loading happens here, but access errors can happen. What is the current behavior for the exceptions above? |
If be happy if there was a switch in the configuration to enable/disable automatic scanning of assemblies. If enabled, I'd like to be able to exclude specific assemblies by name. If disabled, I'd like to be able to include specific assemblies by name. It would also be nice to be able to override this behaviour in code and supply an array of assemblies that can be located via reflection. I'm unclear why there would be a requirement to include assemblies by their path (relative or absolute)? |
@sergeybykov, it might seem like a basic question, well... I guess it is: does the Orleans client have to to scan the assemblies on initialization? Is there a technical limitation that prevents it from applying the Orleans magic dynamically to assemblies as they're loaded ? |
@globeport Couldn't we achieve both goals by turning off scanning when an explicit list of application assemblies is provided? Otherwise, scan like we do today. We'd still need to load Orleans assemblies regardless, of course. @shayhatsor The reason Orleans client scans assemblies IIRC is for stream providers. We might be able to do away with that because providers are explicitly defined in config. |
Sure, sorry I was thinking that it would be nice to exclude problem assemblies, but if the scan is updated to exclude native assemblies then its probably not required. Providing a single include list to override automatic scanning (via the configuration file or via code) would be perfect. |
Closing this, as we don't scan all assemblies by default in 2.0.0. |
I'm getting the following output running Orleans from an asp.net core app... (.Net Framwork 4.6.1)
The application runs successfully beyond this.
[2016-06-14 13:25:23.041 GMT 6 ERROR 101716 AssemblyLoader.Client ] !!!!!!!!!! An unexpected exception occurred while attempting to load an assembly.
Exc level 0: System.BadImageFormatException: Could not load file or assembly 'file:///C:\Tentacle\Applications\Test\WebApi\0.1.20160614.2_1\libuv.dll' or one of its dependencies. The module was expected to contain an assembly manifest.
at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadFrom(String assemblyFile, Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm, Boolean forIntrospection, Boolean suppressSecurityChecks, StackCrawlMark& stackMark)
at System.Reflection.Assembly.ReflectionOnlyLoadFrom(String assemblyFile)
at Orleans.Runtime.AssemblyLoader.ReflectionOnlyLoadAssembly(String pathName, Assembly& assembly, String[]& complaints)
A ReflectionTypeLoadException has been thrown. The original exception and the contents of the LoaderExceptions property have been aggregated for your convenience.
Exception = System.AggregateException: A ReflectionTypeLoadException has been thrown. The original exception and the contents of the LoaderExceptions property have been aggregated for your convenience. ---> System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
at System.Reflection.RuntimeAssembly.get_DefinedTypes()
at Orleans.Runtime.AssemblyLoaderReflectionCriterion.<>c__DisplayClass3_0.b__0(Assembly assembly, IEnumerable
1& assemblyComplaints) --- End of inner exception stack trace --- at Orleans.Runtime.Utils.Flatten(ReflectionTypeLoadException rtle) at Orleans.Runtime.AssemblyLoaderReflectionCriterion.<>c__DisplayClass3_0.<NewCriterion>b__0(Assembly assembly, IEnumerable
1& assemblyComplaints)at Orleans.Runtime.AssemblyLoaderCriterion.EvaluateCandidate(Object input, IEnumerable
1& complaints) at Orleans.Runtime.AssemblyLoader.ShouldLoadAssembly(String pathName) ---> (Inner Exception #0) System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information. at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module) at System.Reflection.RuntimeAssembly.get_DefinedTypes() at Orleans.Runtime.AssemblyLoaderReflectionCriterion.<>c__DisplayClass3_0.<NewCriterion>b__0(Assembly assembly, IEnumerable
1& assemblyComplaints)<---...
...
---> (Inner Exception #1) System.TypeLoadException: Could not load type 'System.Object' from assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' because the parent does not exist.<---
---> (Inner Exception #2) System.TypeLoadException: Could not load type 'System.Object' from assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' because the parent does not exist.<---
...
...
Hosting environment: Production
Content root path: C:\Tentacle\Applications\Test\WebApi\0.1.20160614.2_1
Now listening on: http://localhost:4306/
Application started. Press Ctrl+C to shut down.
The text was updated successfully, but these errors were encountered: