You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@river.apache.org by pe...@apache.org on 2014/05/19 12:54:16 UTC

svn commit: r1595826 - in /river/jtsk/skunk/qa_refactor/trunk/src: com/sun/jini/resource/ com/sun/jini/start/ net/jini/config/ net/jini/loader/ net/jini/loader/pref/

Author: peter_firmstone
Date: Mon May 19 10:54:16 2014
New Revision: 1595826

URL: http://svn.apache.org/r1595826
Log:
Move forName method out of ClassLoading, to avoid causing early loading of ClassLoading class, in case RMIClassLoaderSpi providers aren't ready.

Added:
    river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/LoadClass.java
Modified:
    river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/resource/Service.java
    river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/start/ActivateWrapper.java
    river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/start/NonActivatableServiceDescriptor.java
    river/jtsk/skunk/qa_refactor/trunk/src/net/jini/config/ConfigurationFile.java
    river/jtsk/skunk/qa_refactor/trunk/src/net/jini/config/ConfigurationProvider.java
    river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/ClassLoading.java
    river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/pref/PreferredClassProvider.java

Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/resource/Service.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/resource/Service.java?rev=1595826&r1=1595825&r2=1595826&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/resource/Service.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/resource/Service.java Mon May 19 10:54:16 2014
@@ -32,6 +32,7 @@ import java.util.Set;
 import java.util.LinkedHashSet;
 import java.util.logging.Logger;
 import net.jini.loader.ClassLoading;
+import net.jini.loader.LoadClass;
 
 
 /**
@@ -274,7 +275,7 @@ public final class Service {
 	    String cn = nextName;
 	    nextName = null;
 	    try {
-		Class c = ClassLoading.forName(cn, true, loader);
+		Class c = LoadClass.forName(cn, true, loader);
 		if (!service.isAssignableFrom(c)) {
 			log.severe("service classloader is "
 					  + service.getClass().getClassLoader()

Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/start/ActivateWrapper.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/start/ActivateWrapper.java?rev=1595826&r1=1595825&r2=1595826&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/start/ActivateWrapper.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/start/ActivateWrapper.java Mon May 19 10:54:16 2014
@@ -55,6 +55,7 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 import net.jini.io.MarshalledInstance;
 import net.jini.loader.ClassLoading;
+import net.jini.loader.LoadClass;
 
 /**
  * A wrapper for activatable objects, providing separation of the import
@@ -465,7 +466,7 @@ public class ActivateWrapper implements 
 	    }
 	
 	    boolean initialize = false;
-	    Class ac = ClassLoading.forName(desc.className, initialize, cl);
+	    Class ac = LoadClass.forName(desc.className, initialize, cl);
  	    logger.log(Level.FINEST, "Obtained implementation class: {0}", ac);
 
 	    t.setContextClassLoader(cl);

Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/start/NonActivatableServiceDescriptor.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/start/NonActivatableServiceDescriptor.java?rev=1595826&r1=1595825&r2=1595826&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/start/NonActivatableServiceDescriptor.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/start/NonActivatableServiceDescriptor.java Mon May 19 10:54:16 2014
@@ -45,6 +45,7 @@ import java.util.Arrays;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import net.jini.loader.ClassLoading;
+import net.jini.loader.LoadClass;
 
 /**
  * Class used to launch shared, non-activatable, in-process 
@@ -653,7 +654,7 @@ public class NonActivatableServiceDescri
         logger.finest("Attempting to get implementation class");
         Class implClass = null;
         implClass = 	
-            ClassLoading.forName(getImplClassName(), false, newClassLoader);
+            LoadClass.forName(getImplClassName(), false, newClassLoader);
         logger.finest("Setting context class loader");
         curThread.setContextClassLoader(newClassLoader);
 

Modified: river/jtsk/skunk/qa_refactor/trunk/src/net/jini/config/ConfigurationFile.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/net/jini/config/ConfigurationFile.java?rev=1595826&r1=1595825&r2=1595826&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/net/jini/config/ConfigurationFile.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/net/jini/config/ConfigurationFile.java Mon May 19 10:54:16 2014
@@ -57,6 +57,7 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 import net.jini.export.Exporter;
 import net.jini.loader.ClassLoading;
+import net.jini.loader.LoadClass;
 import net.jini.security.ProxyPreparer;
 import net.jini.security.Security;
 
@@ -2334,7 +2335,7 @@ public class ConfigurationFile extends A
 	throws ConfigurationException
     {
 	try {
-	    Class result = ClassLoading.forName(name, false, cl);
+	    Class result = LoadClass.forName(name, false, cl);
 	    Class c = result;
 	    do {
 		if (!Modifier.isPublic(c.getModifiers())) {

Modified: river/jtsk/skunk/qa_refactor/trunk/src/net/jini/config/ConfigurationProvider.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/net/jini/config/ConfigurationProvider.java?rev=1595826&r1=1595825&r2=1595826&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/net/jini/config/ConfigurationProvider.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/net/jini/config/ConfigurationProvider.java Mon May 19 10:54:16 2014
@@ -33,6 +33,7 @@ import java.util.Enumeration;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import net.jini.loader.ClassLoading;
+import net.jini.loader.LoadClass;
 import net.jini.security.Security;
 
 /**
@@ -241,7 +242,7 @@ public class ConfigurationProvider {
 	    return new ConfigurationFile(options, cl);
 	}
 	try {
-	    Class cls = ClassLoading.forName(cname, true, resourceLoader);
+	    Class cls = LoadClass.forName(cname, true, resourceLoader);
 	    if (!Configuration.class.isAssignableFrom(cls)) {
 		configEx = new ConfigurationException(
 		    "provider class " + cname +

Modified: river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/ClassLoading.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/ClassLoading.java?rev=1595826&r1=1595825&r2=1595826&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/ClassLoading.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/ClassLoading.java Mon May 19 10:54:16 2014
@@ -18,9 +18,6 @@
 
 package net.jini.loader;
 
-import au.net.zeus.collection.RC;
-import au.net.zeus.collection.Ref;
-import au.net.zeus.collection.Referrer;
 import java.lang.ref.SoftReference;
 import java.net.MalformedURLException;
 import java.rmi.server.RMIClassLoader;
@@ -32,19 +29,9 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.ServiceLoader;
 import java.util.WeakHashMap;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import net.jini.security.Security;
-import org.apache.river.impl.thread.NamedThreadFactory;
 
 /**
  * Provides static methods for loading classes using {@link
@@ -202,22 +189,6 @@ public final class ClassLoading {
             return provider(providerName, providerLoader);
         }
     }
-    
-    /**
-     * loaderMap contains a list of single threaded ExecutorService's for
-     * each ClassLoader, used for loading classes and proxies to avoid 
-     * ClassLoader lock contention. An Entry is removed if the ClassLoader
-     * becomes weakly reachable, or the ExecutorService hasn't been used
-     * recently.
-     */
-    private static final ConcurrentMap<ClassLoader,ExecutorService> loaderMap 
-            = RC.concurrentMap(
-                new ConcurrentHashMap<Referrer<ClassLoader>,Referrer<ExecutorService>>(),
-                Ref.WEAK_IDENTITY,
-                Ref.TIME,
-                10000L,
-                10000L
-            );
 
     /**
      * per-thread cache (weakly) mapping verifierLoader values to
@@ -543,95 +514,6 @@ public final class ClassLoading {
 	verifiedCodebases.put(codebase, new SoftReference(codebase));
 	return;
     }
-    
-    /**
-     * Returns the {@code Class} object associated with the class or
-     * interface with the given string name, using the given class loader.
-     * 
-     * This method calls {@link Class#forName(String,boolean,ClassLoader)}, 
-     * from a Thread dedicated for each
-     * ClassLoader, avoiding contention for ClassLoader locks by thread
-     * confinement.  This provides a significant scalability benefit for
-     * JERI, without needing to resort to parallel ClassLoader locks, which 
-     * isn't part of the Java specification.
-     * 
-     * If loader is null, thread confinement is not used.
-     * 
-     * @param name       fully qualified name of the desired class
-     * @param initialize whether the class must be initialized
-     * @param loader     class loader from which the class must be loaded
-     * @return           class object representing the desired class
-     *
-     * @exception LinkageError if the linkage fails
-     * @exception ExceptionInInitializerError if the initialization provoked
-     *            by this method fails
-     * @exception ClassNotFoundException if the class cannot be located by
-     *            the specified class loader
-     * @see Class
-     * @since 3.0
-     */
-    public static Class<?> forName(String name, boolean initialize,
-                                   ClassLoader loader)
-        throws ClassNotFoundException
-    {
-        if (loader == null) return Class.forName(name, initialize, loader);
-        // Don't thread confine profiler ClassLoaders.
-        if (loader.toString().startsWith("javax.management.remote.rmi.RMIConnectionImpl") ) 
-            return Class.forName(name, initialize, loader);
-            
-        ExecutorService exec = loaderMap.get(loader);
-        if (exec == null){
-            exec = new ThreadPoolExecutor(
-                    1,
-                    1,
-                    0,
-                    TimeUnit.SECONDS,
-                    new LinkedBlockingQueue(),
-                    new NamedThreadFactory(loader.toString(),false),
-                    new ThreadPoolExecutor.CallerRunsPolicy()
-            );
-            ExecutorService existed = loaderMap.putIfAbsent(loader, exec);
-            if (existed != null){
-                exec = existed;
-            }
-        }
-        FutureTask<Class> future = new FutureTask(new GetClassTask(name, initialize, loader));
-        exec.submit(future);
-        try {
-            return future.get();
-        } catch (InterruptedException e){
-            e.fillInStackTrace();
-            throw new ClassNotFoundException("Interrupted, Unable to find Class: " + name, e);
-        } catch (ExecutionException e){
-            Throwable t = e.getCause();
-            if (t instanceof LinkageError) throw (LinkageError) t;
-            if (t instanceof ExceptionInInitializerError) 
-                throw (ExceptionInInitializerError) t;
-            if (t instanceof SecurityException) throw (SecurityException) t;
-            if (t instanceof ClassNotFoundException ) 
-                throw (ClassNotFoundException) t;
-            if (t instanceof NullPointerException) throw (NullPointerException) t;
-            throw new ClassNotFoundException("Unable to find Class:" + name, t);
-        }
-    }
-    
-    private static class GetClassTask implements Callable<Class> {
-        private final String name;
-        private final boolean initialize;
-        private final ClassLoader loader;
-        
-        private GetClassTask(String name, boolean initialize, ClassLoader loader){
-            this.name = name;
-            this.initialize = initialize;
-            this.loader = loader;
-        }
-
-        @Override
-        public Class call() throws ClassNotFoundException {
-            return Class.forName(name, initialize, loader);
-        }
-        
-    }
 
     private ClassLoading() { throw new AssertionError(); }
 }

Added: river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/LoadClass.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/LoadClass.java?rev=1595826&view=auto
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/LoadClass.java (added)
+++ river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/LoadClass.java Mon May 19 10:54:16 2014
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.jini.loader;
+
+import au.net.zeus.collection.RC;
+import au.net.zeus.collection.Ref;
+import au.net.zeus.collection.Referrer;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import org.apache.river.impl.thread.NamedThreadFactory;
+
+/**
+ * LoadClass delegates to @link {Class#forName(String, boolean, ClassLoader)},
+ * calls to each ClassLoader are thread confined.
+ * 
+ * @author peter
+ */
+public class LoadClass {
+    
+    private LoadClass() {throw new AssertionError();}
+    /**
+     * loaderMap contains a list of single threaded ExecutorService's for
+     * each ClassLoader, used for loading classes and proxies to avoid
+     * ClassLoader lock contention. An Entry is removed if the ClassLoader
+     * becomes weakly reachable, or the ExecutorService hasn't been used
+     * recently.
+     */
+    private static final ConcurrentMap<ClassLoader, ExecutorService> loaderMap 
+            = RC.concurrentMap(
+                    new ConcurrentHashMap<Referrer<ClassLoader>,
+                    Referrer<ExecutorService>>(),
+                    Ref.WEAK_IDENTITY,
+                    Ref.TIME,
+                    10000L,
+                    10000L
+            );
+
+    /**
+     * Returns the {@code Class} object associated with the class or
+     * interface with the given string name, using the given class loader.
+     *
+     * This method calls {@link Class#forName(String,boolean,ClassLoader)},
+     * from a Thread dedicated for each
+     * ClassLoader, avoiding contention for ClassLoader locks by thread
+     * confinement.  This provides a significant scalability benefit for
+     * JERI, without needing to resort to parallel ClassLoader locks, which
+     * isn't part of the Java specification.
+     *
+     * If loader is null, thread confinement is not used.
+     *
+     * @param name       fully qualified name of the desired class
+     * @param initialize whether the class must be initialized
+     * @param loader     class loader from which the class must be loaded
+     * @return           class object representing the desired class
+     *
+     * @exception LinkageError if the linkage fails
+     * @exception ExceptionInInitializerError if the initialization provoked
+     *            by this method fails
+     * @exception ClassNotFoundException if the class cannot be located by
+     *            the specified class loader
+     * @see Class
+     * @since 3.0
+     */
+    public static Class forName(String name, boolean initialize, ClassLoader loader) 
+            throws ClassNotFoundException 
+    {
+        if (loader == null) return Class.forName(name, initialize, loader);
+        if (loader.toString().startsWith(
+                "javax.management.remote.rmi.RMIConnectionImpl")) 
+        {
+            return Class.forName(name, initialize, loader);
+        }
+        ExecutorService exec = loaderMap.get(loader);
+        if (exec == null) {
+            exec = new ThreadPoolExecutor(
+                    1,
+                    1,
+                    0,
+                    TimeUnit.SECONDS,
+                    new LinkedBlockingQueue(),
+                    new NamedThreadFactory(loader.toString(), false),
+                    new ThreadPoolExecutor.CallerRunsPolicy()
+            );
+            ExecutorService existed = loaderMap.putIfAbsent(loader, exec);
+            if (existed != null) {
+                exec = existed;
+            }
+        }
+        FutureTask<Class> future = 
+                new FutureTask(new GetClassTask(name, initialize, loader));
+        exec.submit(future);
+        try {
+            return future.get();
+        } catch (InterruptedException e) {
+            e.fillInStackTrace();
+            throw new ClassNotFoundException(
+                    "Interrupted, Unable to find Class: " + name, e);
+        } catch (ExecutionException e) {
+            Throwable t = e.getCause();
+            if (t instanceof LinkageError) {
+                throw (LinkageError) t;
+            }
+            if (t instanceof ExceptionInInitializerError) {
+                throw (ExceptionInInitializerError) t;
+            }
+            if (t instanceof SecurityException) {
+                throw (SecurityException) t;
+            }
+            if (t instanceof ClassNotFoundException) {
+                throw (ClassNotFoundException) t;
+            }
+            if (t instanceof NullPointerException) {
+                throw (NullPointerException) t;
+            }
+            throw new ClassNotFoundException(
+                    "Unable to find Class:" + name, t);
+        }
+    }
+
+    private static class GetClassTask implements Callable<Class> {
+
+        private final String name;
+        private final boolean initialize;
+        private final ClassLoader loader;
+
+        private GetClassTask(String name, boolean initialize, ClassLoader loader) {
+            this.name = name;
+            this.initialize = initialize;
+            this.loader = loader;
+        }
+
+        @Override
+        public Class call() throws ClassNotFoundException {
+            return Class.forName(name, initialize, loader);
+        }
+
+    }
+
+}

Modified: river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/pref/PreferredClassProvider.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/pref/PreferredClassProvider.java?rev=1595826&r1=1595825&r2=1595826&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/pref/PreferredClassProvider.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/pref/PreferredClassProvider.java Mon May 19 10:54:16 2014
@@ -56,6 +56,7 @@ import java.util.logging.Level;
 import net.jini.loader.ClassAnnotation;
 import net.jini.loader.ClassLoading;
 import net.jini.loader.DownloadPermission;
+import net.jini.loader.LoadClass;
 import org.apache.river.api.net.Uri;
 
 /**
@@ -577,7 +578,7 @@ public class PreferredClassProvider exte
 	     urlsMatchLoaderAnnotation(codebaseURIs, defaultLoader)))
 	{
 	    try {
-		Class c = ClassLoading.forName(name, false, defaultLoader);
+		Class c = LoadClass.forName(name, false, defaultLoader);
 		if (logger.isLoggable(Level.FINEST)) {
 		    logger.log(Level.FINEST, "class \"{0}\" found " +
 			"via defaultLoader, defined by {1}",
@@ -609,7 +610,7 @@ public class PreferredClassProvider exte
 	    !(codebaseLoader instanceof PreferredClassLoader))
 	{
 	    try {
-		Class c = ClassLoading.forName(name, false, defaultLoader);
+		Class c = LoadClass.forName(name, false, defaultLoader);
 		if (logger.isLoggable(Level.FINEST)) {
 		    logger.log(Level.FINEST, "class \"{0}\" found " +
 			"via defaultLoader, defined by {1}",
@@ -660,7 +661,7 @@ public class PreferredClassProvider exte
 	    }
 	    if (tryDL) {
 		try {
-		    Class c = ClassLoading.forName(name, false, defaultLoader);
+		    Class c = LoadClass.forName(name, false, defaultLoader);
 		    if (logger.isLoggable(Level.FINEST)) {
 			logger.log(Level.FINEST, "class \"{0}\" found " +
 			    "via defaultLoader, defined by {1}",
@@ -677,7 +678,7 @@ public class PreferredClassProvider exte
 	 * context class loader as appropriate.
 	 */
 	try {
-	    Class c = ClassLoading.forName(name, false,
+	    Class c = LoadClass.forName(name, false,
 				    (sm != null && secEx == null ?
 				     codebaseLoader : contextLoader));
 	    if (logger.isLoggable(Level.FINEST)) {
@@ -1428,7 +1429,7 @@ public class PreferredClassProvider exte
 
 	for (int i = 0; i < interfaces.length; i++) {
 	    Class cl =
-		(classObjs[i] = ClassLoading.forName(interfaces[i], false, loader));
+		(classObjs[i] = LoadClass.forName(interfaces[i], false, loader));
 		
 	    if (!Modifier.isPublic(cl.getModifiers())) {
 		ClassLoader current = getClassLoader(cl);