diff --git a/ikvmc/CompilerClassLoader.cs b/ikvmc/CompilerClassLoader.cs index 5d8e7054..7e755d69 100644 --- a/ikvmc/CompilerClassLoader.cs +++ b/ikvmc/CompilerClassLoader.cs @@ -2755,7 +2755,7 @@ namespace IKVM.Internal AssemblyClassLoader[] referencedAssemblies = new AssemblyClassLoader[references.Count]; for(int i = 0; i < references.Count; i++) { - referencedAssemblies[i] = ClassLoaderWrapper.GetAssemblyClassLoader(references[i]); + referencedAssemblies[i] = AssemblyClassLoader.FromAssembly(references[i]); } loader = new CompilerClassLoader(referencedAssemblies, options, options.path, options.keyfilename, options.keycontainer, options.version, options.targetIsModule, options.assembly, h); loader.baseClasses = baseClasses; @@ -2820,7 +2820,7 @@ namespace IKVM.Internal if(!compilingCoreAssembly) { allReferencesAreStrongNamed &= IsSigned(JVM.CoreAssembly); - loader.AddReference(ClassLoaderWrapper.GetAssemblyClassLoader(JVM.CoreAssembly)); + loader.AddReference(AssemblyClassLoader.FromAssembly(JVM.CoreAssembly)); } if((options.keycontainer != null || options.keyfilename != null) && !allReferencesAreStrongNamed) diff --git a/runtime/AssemblyClassLoader.cs b/runtime/AssemblyClassLoader.cs index 6b1a6e1a..b6779f3e 100644 --- a/runtime/AssemblyClassLoader.cs +++ b/runtime/AssemblyClassLoader.cs @@ -39,6 +39,7 @@ namespace IKVM.Internal { class AssemblyClassLoader : ClassLoaderWrapper { + private static readonly Dictionary assemblyClassLoaders = new Dictionary(); private AssemblyLoader assemblyLoader; private string[] references; private AssemblyClassLoader[] delegates; @@ -46,6 +47,8 @@ namespace IKVM.Internal #if !STATIC_COMPILER private Thread initializerThread; private volatile object protectionDomain; + private static bool customClassLoaderRedirectsLoaded; + private static Dictionary customClassLoaderRedirects; #endif private bool hasCustomClassLoader; private Dictionary> exports; @@ -559,7 +562,7 @@ namespace IKVM.Internal { //Tracer.Info(Tracer.Runtime, "GetWrapperFromAssemblyType: {0}", type.FullName); Debug.Assert(!type.Name.EndsWith("[]"), "!type.IsArray", type.FullName); - Debug.Assert(ClassLoaderWrapper.GetAssemblyClassLoader(type.Assembly) == this); + Debug.Assert(AssemblyClassLoader.FromAssembly(type.Assembly) == this); #if !IKVM_REF_EMIT Debug.Assert(!(type.Assembly is AssemblyBuilder), "!(type.Assembly is AssemblyBuilder)", type.FullName); #endif @@ -611,7 +614,7 @@ namespace IKVM.Internal Assembly asm = LoadAssemblyOrClearName(ref references[i]); if (asm != null) { - delegates[i] = ClassLoaderWrapper.GetAssemblyClassLoader(asm); + delegates[i] = AssemblyClassLoader.FromAssembly(asm); } } if (delegates[i] != null) @@ -699,7 +702,7 @@ namespace IKVM.Internal Assembly asm = LoadAssemblyOrClearName(ref references[i]); if (asm != null) { - delegates[i] = ClassLoaderWrapper.GetAssemblyClassLoader(asm); + delegates[i] = AssemblyClassLoader.FromAssembly(asm); } } if (delegates[i] != null) @@ -847,6 +850,217 @@ namespace IKVM.Internal #endif return GetLoaderForExportedAssembly(GetAssembly(wrapper)).InternalsVisibleTo(otherName); } + + // this method only supports .NET or pre-compiled Java assemblies + internal static AssemblyClassLoader FromAssembly(Assembly assembly) + { +#if !IKVM_REF_EMIT + Debug.Assert(!(assembly is AssemblyBuilder)); +#endif // !IKVM_REF_EMIT + + ConstructorInfo customClassLoaderCtor = null; + AssemblyClassLoader loader; + object javaClassLoader = null; + lock (wrapperLock) + { + if (!assemblyClassLoaders.TryGetValue(assembly, out loader)) + { + // If the assembly is a part of a multi-assembly shared class loader, + // it will export the __ type from the main assembly in the group. + Type forwarder = assembly.GetType("__"); + if (forwarder != null) + { + Assembly mainAssembly = forwarder.Assembly; + if (mainAssembly != assembly) + { + loader = FromAssembly(mainAssembly); + assemblyClassLoaders[assembly] = loader; + return loader; + } + } + if (assembly == JVM.CoreAssembly) + { + // This cast is necessary for ikvmc and a no-op for the runtime. + // Note that the cast cannot fail, because ikvmc will only return a non AssemblyClassLoader + // from GetBootstrapClassLoader() when compiling the core assembly and in that case JVM.CoreAssembly + // will be null. + return (AssemblyClassLoader)GetBootstrapClassLoader(); + } +#if !STATIC_COMPILER && !FIRST_PASS + if (!assembly.ReflectionOnly) + { + Type customClassLoaderClass = null; + LoadCustomClassLoaderRedirects(); + if (customClassLoaderRedirects != null) + { + string assemblyName = assembly.FullName; + foreach (KeyValuePair 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. + // On .NET 2.0 there is AssemblyName.ReferenceMatchesDefinition() + // but it is broken (and .NET 2.0 specific). + 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"); + } + // 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 valid and should anyone cache it, they will get the + // right object to use later on. + // Note also that we're not running the constructor here, because we don't want to run user code while holding a global lock. + javaClassLoader = (java.lang.ClassLoader)CreateUnitializedCustomClassLoader(customClassLoaderClass); + customClassLoaderCtor = customClassLoaderClass.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(Assembly) }, null); + if (customClassLoaderCtor == null) + { + javaClassLoader = null; + throw new Exception("No constructor"); + } + if (!customClassLoaderCtor.IsPublic && !customClassLoaderClass.Assembly.Equals(assembly)) + { + javaClassLoader = null; + throw new Exception("Constructor not accessible"); + } + Tracer.Info(Tracer.Runtime, "Created custom assembly class loader {0} for assembly {1}", customClassLoaderClass.FullName, assembly); + } + 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 = DoPrivileged(new CreateAssemblyClassLoader(assembly)); + } +#endif + loader = new AssemblyClassLoader(assembly, javaClassLoader, customClassLoaderCtor != null); + assemblyClassLoaders[assembly] = loader; +#if !STATIC_COMPILER + if (customClassLoaderCtor != null) + { + loader.SetInitInProgress(); + } + if (javaClassLoader != null) + { + SetWrapperForClassLoader(javaClassLoader, loader); + } +#endif + } + } +#if !STATIC_COMPILER && !FIRST_PASS + if (customClassLoaderCtor != null) + { + try + { + DoPrivileged(new CustomClassLoaderCtorCaller(customClassLoaderCtor, javaClassLoader, assembly)); + } + finally + { + loader.SetInitDone(); + } + } + loader.WaitInitDone(); +#endif + return loader; + } + +#if !STATIC_COMPILER && !FIRST_PASS + private static object CreateUnitializedCustomClassLoader(Type customClassLoaderClass) + { + return System.Runtime.Serialization.FormatterServices.GetUninitializedObject(customClassLoaderClass); + } + + private static void LoadCustomClassLoaderRedirects() + { + // this method assumes that we hold a global lock + if (!customClassLoaderRedirectsLoaded) + { + customClassLoaderRedirectsLoaded = true; + try + { + foreach (string key in System.Configuration.ConfigurationManager.AppSettings.AllKeys) + { + const string prefix = "ikvm-classloader:"; + if (key.StartsWith(prefix)) + { + if (customClassLoaderRedirects == null) + { + customClassLoaderRedirects = new Dictionary(); + } + customClassLoaderRedirects[key.Substring(prefix.Length)] = System.Configuration.ConfigurationManager.AppSettings.Get(key); + } + } + } + catch (Exception x) + { + Tracer.Error(Tracer.Runtime, "Error while reading custom class loader redirects: {0}", x); + } + } + } + + internal sealed class CreateAssemblyClassLoader : java.security.PrivilegedAction + { + private Assembly assembly; + + internal CreateAssemblyClassLoader(Assembly assembly) + { + this.assembly = assembly; + } + + public object run() + { + return new ikvm.runtime.AssemblyClassLoader(assembly); + } + } + + sealed class CustomClassLoaderCtorCaller : java.security.PrivilegedAction + { + private ConstructorInfo ctor; + private object classLoader; + private Assembly assembly; + + internal CustomClassLoaderCtorCaller(ConstructorInfo ctor, object classLoader, Assembly assembly) + { + this.ctor = ctor; + this.classLoader = classLoader; + this.assembly = assembly; + } + + public object run() + { + ctor.Invoke(classLoader, new object[] { assembly }); + return null; + } + } +#endif } class BootstrapClassLoader : AssemblyClassLoader diff --git a/runtime/ClassLoaderWrapper.cs b/runtime/ClassLoaderWrapper.cs index 613b7883..2b10e25a 100644 --- a/runtime/ClassLoaderWrapper.cs +++ b/runtime/ClassLoaderWrapper.cs @@ -47,7 +47,7 @@ namespace IKVM.Internal class ClassLoaderWrapper { - private static readonly object wrapperLock = new object(); + protected static readonly object wrapperLock = new object(); private static readonly Dictionary globalTypeToTypeWrapper = new Dictionary(); #if STATIC_COMPILER private static ClassLoaderWrapper bootstrapClassLoader; @@ -55,12 +55,9 @@ namespace IKVM.Internal #else private static AssemblyClassLoader bootstrapClassLoader; #endif - private static readonly Dictionary assemblyClassLoaders = new Dictionary(); private static List genericClassLoaders; #if !STATIC_COMPILER && !FIRST_PASS private readonly java.lang.ClassLoader javaClassLoader; - private static bool customClassLoaderRedirectsLoaded; - private static Dictionary customClassLoaderRedirects; #endif private TypeWrapperFactory factory; private Dictionary types = new Dictionary(); @@ -931,7 +928,7 @@ namespace IKVM.Internal // if the wrapper doesn't already exist, that must mean that the type // is a .NET type (or a pre-compiled Java class), which means that it // was "loaded" by an assembly classloader - wrapper = GetAssemblyClassLoader(asm).GetWrapperFromAssemblyType(type); + wrapper = AssemblyClassLoader.FromAssembly(asm).GetWrapperFromAssemblyType(type); } #if CLASSGC if(type.Assembly.IsDynamic()) @@ -968,7 +965,7 @@ namespace IKVM.Internal Debug.Assert(!type.ContainsGenericParameters); List list = new List(); - list.Add(GetAssemblyClassLoader(type.Assembly)); + list.Add(AssemblyClassLoader.FromAssembly(type.Assembly)); foreach(Type arg in type.GetGenericArguments()) { ClassLoaderWrapper loader = GetWrapperFromType(arg).GetClassLoader(); @@ -1007,7 +1004,7 @@ namespace IKVM.Internal } object javaClassLoader = null; #if !STATIC_COMPILER && !FIRST_PASS - javaClassLoader = DoPrivileged(new CreateAssemblyClassLoader(null)); + javaClassLoader = DoPrivileged(new AssemblyClassLoader.CreateAssemblyClassLoader(null)); #endif GenericClassLoader newLoader = new GenericClassLoader(key, javaClassLoader); SetWrapperForClassLoader(javaClassLoader, newLoader); @@ -1024,7 +1021,7 @@ namespace IKVM.Internal } #endif - private static void SetWrapperForClassLoader(object javaClassLoader, ClassLoaderWrapper wrapper) + protected static void SetWrapperForClassLoader(object javaClassLoader, ClassLoaderWrapper wrapper) { #if !STATIC_COMPILER && !FIRST_PASS #if __MonoCS__ @@ -1085,9 +1082,9 @@ namespace IKVM.Internal return GetGenericClassLoaderByName(name); } #if STATIC_COMPILER - return ClassLoaderWrapper.GetAssemblyClassLoader(Assembly.ReflectionOnlyLoad(name)); + return AssemblyClassLoader.FromAssembly(Assembly.ReflectionOnlyLoad(name)); #else - return ClassLoaderWrapper.GetAssemblyClassLoader(Assembly.Load(name)); + return AssemblyClassLoader.FromAssembly(Assembly.Load(name)); #endif } @@ -1107,217 +1104,6 @@ namespace IKVM.Internal } } - // this method only supports .NET or pre-compiled Java assemblies - internal static AssemblyClassLoader GetAssemblyClassLoader(Assembly assembly) - { -#if !IKVM_REF_EMIT - Debug.Assert(!(assembly is AssemblyBuilder)); -#endif // !IKVM_REF_EMIT - - ConstructorInfo customClassLoaderCtor = null; - AssemblyClassLoader loader; - object javaClassLoader = null; - lock(wrapperLock) - { - if(!assemblyClassLoaders.TryGetValue(assembly, out loader)) - { - // If the assembly is a part of a multi-assembly shared class loader, - // it will export the __ type from the main assembly in the group. - Type forwarder = assembly.GetType("__"); - if(forwarder != null) - { - Assembly mainAssembly = forwarder.Assembly; - if(mainAssembly != assembly) - { - loader = GetAssemblyClassLoader(mainAssembly); - assemblyClassLoaders[assembly] = loader; - return loader; - } - } - if(assembly == JVM.CoreAssembly) - { - // This cast is necessary for ikvmc and a no-op for the runtime. - // Note that the cast cannot fail, because ikvmc will only return a non AssemblyClassLoader - // from GetBootstrapClassLoader() when compiling the core assembly and in that case JVM.CoreAssembly - // will be null. - return (AssemblyClassLoader)GetBootstrapClassLoader(); - } -#if !STATIC_COMPILER && !FIRST_PASS - if(!assembly.ReflectionOnly) - { - Type customClassLoaderClass = null; - LoadCustomClassLoaderRedirects(); - if(customClassLoaderRedirects != null) - { - string assemblyName = assembly.FullName; - foreach(KeyValuePair 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. - // On .NET 2.0 there is AssemblyName.ReferenceMatchesDefinition() - // but it is broken (and .NET 2.0 specific). - 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"); - } - // 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 valid and should anyone cache it, they will get the - // right object to use later on. - // Note also that we're not running the constructor here, because we don't want to run user code while holding a global lock. - javaClassLoader = (java.lang.ClassLoader)CreateUnitializedCustomClassLoader(customClassLoaderClass); - customClassLoaderCtor = customClassLoaderClass.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(Assembly) }, null); - if(customClassLoaderCtor == null) - { - javaClassLoader = null; - throw new Exception("No constructor"); - } - if(!customClassLoaderCtor.IsPublic && !customClassLoaderClass.Assembly.Equals(assembly)) - { - javaClassLoader = null; - throw new Exception("Constructor not accessible"); - } - Tracer.Info(Tracer.Runtime, "Created custom assembly class loader {0} for assembly {1}", customClassLoaderClass.FullName, assembly); - } - 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 = DoPrivileged(new CreateAssemblyClassLoader(assembly)); - } -#endif - loader = new AssemblyClassLoader(assembly, javaClassLoader, customClassLoaderCtor != null); - assemblyClassLoaders[assembly] = loader; -#if !STATIC_COMPILER - if(customClassLoaderCtor != null) - { - loader.SetInitInProgress(); - } - if(javaClassLoader != null) - { - SetWrapperForClassLoader(javaClassLoader, loader); - } -#endif - } - } -#if !STATIC_COMPILER && !FIRST_PASS - if(customClassLoaderCtor != null) - { - try - { - DoPrivileged(new CustomClassLoaderCtorCaller(customClassLoaderCtor, javaClassLoader, assembly)); - } - finally - { - loader.SetInitDone(); - } - } - loader.WaitInitDone(); -#endif - return loader; - } - -#if !STATIC_COMPILER && !FIRST_PASS - private static object CreateUnitializedCustomClassLoader(Type customClassLoaderClass) - { - return System.Runtime.Serialization.FormatterServices.GetUninitializedObject(customClassLoaderClass); - } - - private static void LoadCustomClassLoaderRedirects() - { - // this method assumes that we hold a global lock - if(!customClassLoaderRedirectsLoaded) - { - customClassLoaderRedirectsLoaded = true; - try - { - foreach(string key in System.Configuration.ConfigurationManager.AppSettings.AllKeys) - { - const string prefix = "ikvm-classloader:"; - if(key.StartsWith(prefix)) - { - if(customClassLoaderRedirects == null) - { - customClassLoaderRedirects = new Dictionary(); - } - customClassLoaderRedirects[key.Substring(prefix.Length)] = System.Configuration.ConfigurationManager.AppSettings.Get(key); - } - } - } - catch(Exception x) - { - Tracer.Error(Tracer.Runtime, "Error while reading custom class loader redirects: {0}", x); - } - } - } - - sealed class CreateAssemblyClassLoader : java.security.PrivilegedAction - { - private Assembly assembly; - - internal CreateAssemblyClassLoader(Assembly assembly) - { - this.assembly = assembly; - } - - public object run() - { - return new ikvm.runtime.AssemblyClassLoader(assembly); - } - } - - sealed class CustomClassLoaderCtorCaller : java.security.PrivilegedAction - { - private ConstructorInfo ctor; - private object classLoader; - private Assembly assembly; - - internal CustomClassLoaderCtorCaller(ConstructorInfo ctor, object classLoader, Assembly assembly) - { - this.ctor = ctor; - this.classLoader = classLoader; - this.assembly = assembly; - } - - public object run() - { - ctor.Invoke(classLoader, new object[] { assembly }); - return null; - } - } -#endif - internal void SetWrapperForType(Type type, TypeWrapper wrapper) { TypeWrapper.AssertFinished(type); diff --git a/runtime/DotNetTypeWrapper.cs b/runtime/DotNetTypeWrapper.cs index d1065958..4057c890 100644 --- a/runtime/DotNetTypeWrapper.cs +++ b/runtime/DotNetTypeWrapper.cs @@ -334,7 +334,7 @@ namespace IKVM.Internal internal override ClassLoaderWrapper GetClassLoader() { - return ClassLoaderWrapper.GetAssemblyClassLoader(type.Assembly); + return AssemblyClassLoader.FromAssembly(type.Assembly); } protected override void LazyPublishMembers() @@ -1530,7 +1530,7 @@ namespace IKVM.Internal } if (tw == null) { - tw = ClassLoaderWrapper.GetAssemblyClassLoader(type.Assembly).GetWrapperFromAssemblyType(type); + tw = AssemblyClassLoader.FromAssembly(type.Assembly).GetWrapperFromAssemblyType(type); lock (types) { types[type] = tw; @@ -1596,7 +1596,7 @@ namespace IKVM.Internal { return ClassLoaderWrapper.GetGenericClassLoader(this); } - return ClassLoaderWrapper.GetAssemblyClassLoader(type.Assembly); + return AssemblyClassLoader.FromAssembly(type.Assembly); } private sealed class MulticastDelegateCtorMethodWrapper : MethodWrapper diff --git a/runtime/TypeWrapper.cs b/runtime/TypeWrapper.cs index f24ea97c..0865a351 100644 --- a/runtime/TypeWrapper.cs +++ b/runtime/TypeWrapper.cs @@ -3865,7 +3865,7 @@ namespace IKVM.Internal internal override ClassLoaderWrapper GetClassLoader() { - return ClassLoaderWrapper.GetAssemblyClassLoader(type.Assembly); + return AssemblyClassLoader.FromAssembly(type.Assembly); } private static ExModifiers GetModifiers(Type type) diff --git a/runtime/common.cs b/runtime/common.cs index 53b0907b..e75ba700 100644 --- a/runtime/common.cs +++ b/runtime/common.cs @@ -74,7 +74,7 @@ namespace IKVM.NativeCode.gnu.java.net.protocol.ikvmres public static object LoadClassFromAssembly(Assembly asm, string className) { - TypeWrapper tw = ClassLoaderWrapper.GetAssemblyClassLoader(asm).LoadClassByDottedNameFast(className); + TypeWrapper tw = AssemblyClassLoader.FromAssembly(asm).LoadClassByDottedNameFast(className); if(tw != null) { return tw.ClassObject; @@ -125,7 +125,7 @@ namespace IKVM.NativeCode.ikvm.@internal public static object GetAssemblyClassLoader(Assembly asm) { - return ClassLoaderWrapper.GetAssemblyClassLoader(asm).GetJavaClassLoader(); + return AssemblyClassLoader.FromAssembly(asm).GetJavaClassLoader(); } } @@ -202,7 +202,7 @@ namespace IKVM.NativeCode.ikvm.runtime } else if(assembly != null) { - AssemblyClassLoader_ acl = ClassLoaderWrapper.GetAssemblyClassLoader(assembly); + AssemblyClassLoader_ acl = global::IKVM.Internal.AssemblyClassLoader.FromAssembly(assembly); tw = acl.GetLoadedClass(name); if(tw == null) { @@ -234,7 +234,7 @@ namespace IKVM.NativeCode.ikvm.runtime public static Assembly[] FindResourceAssemblies(Assembly assembly, string name, bool firstOnly) { - IKVM.Internal.AssemblyClassLoader wrapper = ClassLoaderWrapper.GetAssemblyClassLoader(assembly); + IKVM.Internal.AssemblyClassLoader wrapper = IKVM.Internal.AssemblyClassLoader.FromAssembly(assembly); Assembly[] assemblies = wrapper.FindResourceAssemblies(name, firstOnly); if(assemblies == null || assemblies.Length == 0) { @@ -258,7 +258,7 @@ namespace IKVM.NativeCode.ikvm.runtime // NOTE the array may contain duplicates! public static string[] GetPackages(Assembly assembly) { - IKVM.Internal.AssemblyClassLoader wrapper = ClassLoaderWrapper.GetAssemblyClassLoader(assembly); + IKVM.Internal.AssemblyClassLoader wrapper = IKVM.Internal.AssemblyClassLoader.FromAssembly(assembly); string[] packages = new string[0]; foreach(Module m in wrapper.MainAssembly.GetModules(false)) { @@ -307,7 +307,7 @@ namespace IKVM.NativeCode.ikvm.runtime { return null; } - TypeWrapper tw = ClassLoaderWrapper.GetAssemblyClassLoader(asm).DoLoad(className); + TypeWrapper tw = IKVM.Internal.AssemblyClassLoader.FromAssembly(asm).DoLoad(className); return tw != null ? tw.ClassObject : null; } diff --git a/runtime/openjdk.cs b/runtime/openjdk.cs index faa4e799..e6a6995a 100644 --- a/runtime/openjdk.cs +++ b/runtime/openjdk.cs @@ -5398,7 +5398,7 @@ namespace IKVM.NativeCode.sun.misc { if (extcl == null || asm.IsDefined(typeof(IKVM.Attributes.CustomAssemblyClassLoaderAttribute), false)) { - return ClassLoaderWrapper.GetAssemblyClassLoader(asm).GetJavaClassLoader(); + return AssemblyClassLoader.FromAssembly(asm).GetJavaClassLoader(); } return null; }