Пример #1
0
        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;
                    // 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);
            }
        }