internal static TypeWrapper LoadClassNoThrow(ClassLoaderWrapper classLoader, string name) { try { TypeWrapper wrapper = classLoader.LoadClassByDottedNameFast(name); if (wrapper == null) { Tracer.Error(Tracer.ClassLoading, "Class not found: {0}", name); wrapper = new UnloadableTypeWrapper(name); } return(wrapper); } catch (RetargetableJavaException x) { // HACK keep the compiler from warning about unused local GC.KeepAlive(x); #if !STATIC_COMPILER && !FIRST_PASS && !STUB_GENERATOR if (Tracer.ClassLoading.TraceError) { java.lang.ClassLoader cl = (java.lang.ClassLoader)classLoader.GetJavaClassLoader(); if (cl != null) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); string sep = ""; while (cl != null) { sb.Append(sep).Append(cl); sep = " -> "; cl = cl.getParent(); } Tracer.Error(Tracer.ClassLoading, "ClassLoader chain: {0}", sb); } Exception m = ikvm.runtime.Util.mapException(x.ToJava()); Tracer.Error(Tracer.ClassLoading, m.ToString() + Environment.NewLine + m.StackTrace); } #endif // !STATIC_COMPILER && !FIRST_PASS && !STUB_GENERATOR return(new UnloadableTypeWrapper(name)); } }
private void InitializeJavaClassLoader() { Assembly assembly = assemblyLoader.Assembly; { Type customClassLoaderClass = null; LoadCustomClassLoaderRedirects(); string assemblyName = assembly.FullName; foreach (KeyValuePair <string, string> kv in customClassLoaderRedirects) { string asm = kv.Key; // FXBUG // We only support matching on the assembly's simple name, // because there appears to be no viable alternative. // There is AssemblyName.ReferenceMatchesDefinition() // but it is completely broken. if (assemblyName.StartsWith(asm + ",")) { try { customClassLoaderClass = Type.GetType(kv.Value, true); } catch (Exception x) { Tracer.Error(Tracer.Runtime, "Unable to load custom class loader {0} specified in app.config for assembly {1}: {2}", kv.Value, assembly, x); } break; } } if (customClassLoaderClass == null) { object[] attribs = assembly.GetCustomAttributes(typeof(CustomAssemblyClassLoaderAttribute), false); if (attribs.Length == 1) { customClassLoaderClass = ((CustomAssemblyClassLoaderAttribute)attribs[0]).Type; } } if (customClassLoaderClass != null) { try { if (!customClassLoaderClass.IsPublic && !customClassLoaderClass.Assembly.Equals(assembly)) { throw new Exception("Type not accessible"); } ConstructorInfo customClassLoaderCtor = customClassLoaderClass.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(Assembly) }, null); if (customClassLoaderCtor == null) { throw new Exception("No constructor"); } if (!customClassLoaderCtor.IsPublic && !customClassLoaderClass.Assembly.Equals(assembly)) { customClassLoaderCtor = null; throw new Exception("Constructor not accessible"); } hasCustomClassLoader = true; // NOTE we're creating an uninitialized instance of the custom class loader here, so that getClassLoader will return the proper object // when it is called during the construction of the custom class loader later on. This still doesn't make it safe to use the custom // class loader before it is constructed, but at least the object instance is available and should anyone cache it, they will get the // right object to use later on. // Note that creating the unitialized instance will (unfortunately) trigger the static initializer. The static initializer can // trigger a call to getClassLoader(), which means we can end up here recursively. java.lang.ClassLoader newJavaClassLoader = (java.lang.ClassLoader)GetUninitializedObject(customClassLoaderClass); if (javaClassLoader == null) // check if we weren't invoked recursively and the nested invocation already did the work { javaClassLoader = newJavaClassLoader; SetWrapperForClassLoader(javaClassLoader, this); DoPrivileged(new CustomClassLoaderCtorCaller(customClassLoaderCtor, javaClassLoader, assembly)); Tracer.Info(Tracer.Runtime, "Created custom assembly class loader {0} for assembly {1}", customClassLoaderClass.FullName, assembly); } else { // we didn't initialize the object, so there is no need to finalize it GC.SuppressFinalize(newJavaClassLoader); } } catch (Exception x) { Tracer.Error(Tracer.Runtime, "Unable to create custom assembly class loader {0} for {1}: {2}", customClassLoaderClass.FullName, assembly, x); } } } if (javaClassLoader == null) { javaClassLoader = (java.lang.ClassLoader)DoPrivileged(new CreateAssemblyClassLoader(assembly)); SetWrapperForClassLoader(javaClassLoader, this); } }