Example #1
0
 private void InitializeJavaClassLoader(JavaClassLoaderConstructionInProgress jclcip, Type customClassLoaderClass)
 {
     Assembly assembly = assemblyLoader.Assembly;
     {
         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");
                 }
                 // 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 (jclcip.javaClassLoader == null) // check if we weren't invoked recursively and the nested invocation already did the work
                 {
                     jclcip.javaClassLoader = newJavaClassLoader;
                     SetWrapperForClassLoader(jclcip.javaClassLoader, this);
                     DoPrivileged(new CustomClassLoaderCtorCaller(customClassLoaderCtor, jclcip.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 (jclcip.javaClassLoader == null)
     {
         jclcip.javaClassLoader = new ikvm.runtime.AssemblyClassLoader();
         SetWrapperForClassLoader(jclcip.javaClassLoader, this);
     }
     // finally we publish the class loader for other threads to see
     Thread.MemoryBarrier();
     javaClassLoader = jclcip.javaClassLoader;
 }
Example #2
0
 private java.lang.ClassLoader WaitInitializeJavaClassLoader(Type customClassLoader)
 {
     Interlocked.CompareExchange(ref jclcip, new JavaClassLoaderConstructionInProgress(), null);
     JavaClassLoaderConstructionInProgress curr = jclcip;
     if (curr != null)
     {
         if (curr.Thread == Thread.CurrentThread)
         {
             if (curr.javaClassLoader != null)
             {
                 // we were recursively invoked during the class loader construction,
                 // so we have to return the partialy constructed class loader
                 return curr.javaClassLoader;
             }
             curr.recursion++;
             try
             {
                 if (javaClassLoader == null)
                 {
                     InitializeJavaClassLoader(curr, customClassLoader);
                 }
             }
             finally
             {
                 // We only publish the class loader from the outer most invocation, otherwise
                 // an invocation of getClassLoader in the static initializer or constructor
                 // of the custom class loader would result in prematurely publishing it.
                 if (--curr.recursion == 0)
                 {
                     lock (this)
                     {
                         jclcip = null;
                         Monitor.PulseAll(this);
                     }
                 }
             }
         }
         else
         {
             lock (this)
             {
                 while (jclcip != null)
                 {
                     Monitor.Wait(this);
                 }
             }
         }
     }
     return javaClassLoader;
 }