river-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From peter_firmst...@apache.org
Subject svn commit: r1590226 - /river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/ClassLoading.java
Date Sat, 26 Apr 2014 11:30:15 GMT
Author: peter_firmstone
Date: Sat Apr 26 11:30:15 2014
New Revision: 1590226

URL: http://svn.apache.org/r1590226
Log:
RIVER-336 Minor update to ClassLoading to allow modular frameworks to specify the ClassLoader
used to load a RMIClassLoaderSpi provider.

Modified:
    river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/ClassLoading.java

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=1590226&r1=1590225&r2=1590226&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 Sat Apr 26 11:30:15
2014
@@ -26,6 +26,7 @@ import java.net.MalformedURLException;
 import java.rmi.server.RMIClassLoader;
 import java.rmi.server.RMIClassLoaderSpi;
 import java.security.AccessController;
+import java.security.Guard;
 import java.security.PrivilegedAction;
 import java.util.Iterator;
 import java.util.Map;
@@ -65,7 +66,7 @@ import org.apache.river.impl.thread.Name
  * from ClassLoading's own ClassLoader.
  * </p><p>
  * To define a new RMIClassLoaderSpi for River to utilize, create a file in
- * your application jar file called:
+ * your providers jar file called:
  * </p><p>
  * META-INF/services/java.rmi.server.RMIClassLoaderSpi
  * </p><p>
@@ -77,19 +78,26 @@ import org.apache.river.impl.thread.Name
  * </p><p>
  * System.getProperty("net.jini.loader.ClassLoading.provider");
  * </p><p>
- * If this System property is not defined, ClassLoading will load the first 
- * provider found.
+ * If this System property is not defined, ClassLoading will load 
+ * <code>net.jini.loader.pref.PreferredClassProvider</code>, alternatively
+ * <code>java.rmi.server.RMIClassLoader</code> delegates all calls to {@link
+ * RMIClassLoader}.
+ * </p><p>
+ * If a provider is not found, it will not be updated.
  * </p><p>
  * <h1>History</h1>
  * <p>Gregg Wonderly originally reported River-336 and provided a patch
  * containing a new CodebaseAccessClassLoader to replace {@link RMIClassLoader}, 
- * later Sim Isjkes created RiverClassLoader that utilised ServiceLoader.
+ * later Sim Isjkes created RiverClassLoader that utilized ServiceLoader.
  * Both implementations contained methods identical to {@link RMIClassLoaderSpi},
  * however new implementations were required to extend new provider 
  * implementations, creating a compatibility issue with existing implementations
  * extending {@link RMIClassLoaderSpi}.  For backward compatibility with existing
  * implementations, {@link RMIClassLoaderSpi} has been retained as the provider,
- * avoiding the need to recompile client code.  
+ * avoiding the need to recompile client code.  The abilities of both
+ * implementations, to use ServiceLoader, or to define a provider using a method
+ * call have been retained, with the restriction that implementations are to be
+ * obtained via ServiceLoader.
  * </p><p>
  * Instead, all that is required for utilization of existing service provider
  * {@link RMIClassLoaderSpi} implementations is to set the system property
@@ -100,32 +108,55 @@ import org.apache.river.impl.thread.Name
  **/
 public final class ClassLoading {
     private final static Logger logger = Logger.getLogger(ClassLoading.class.getName());
-    private static final RMIClassLoaderSpi provider;
+    private static volatile RMIClassLoaderSpi provider;
+    private static final Object lock = new Object();
+    private static final Guard permission = new RuntimePermission("setFactory");
     
     static {
-        provider = AccessController.doPrivileged(
+        provider(null, ClassLoading.class.getClassLoader());
+    }
+    
+    /**
+     * The current RMIClassLoaderSpi provider in use by ClassLoading.
+     * 
+     * @return currently installed Provider, may be null.
+     * @throws SecurityException if caller doesn't have RuntimePermission "getFactory"
+     */
+    public static RMIClassLoaderSpi getProvider(){
+        permission.checkGuard(null);
+        return provider;
+    }
+    
+    private static boolean provider(
+            final String providerName, 
+            final ClassLoader providerLoader)
+    {
+        RMIClassLoaderSpi newProvider = AccessController.doPrivileged(
         new PrivilegedAction<RMIClassLoaderSpi>(){
             @Override
             public RMIClassLoaderSpi run() {
-               String providerClassName =
-                    System.getProperty("net.jini.loader.ClassLoading.provider");
-               ServiceLoader<RMIClassLoaderSpi> loader 
-                       = ServiceLoader.load(RMIClassLoaderSpi.class,
-                               ClassLoading.class.getClassLoader());
+                String name = providerName;
+                if (name == null){
+                    name = System.getProperty(
+                            "net.jini.loader.ClassLoading.provider");
+                    if (name == null) {
+                        name = "net.jini.loader.pref.PreferredClassProvider";
+                    } else if ("java.rmi.server.RMIClassLoader".equals(name)){
+                        return null;
+                    }
+                }
+                ServiceLoader<RMIClassLoaderSpi> loader 
+                   = ServiceLoader.load(RMIClassLoaderSpi.class, providerLoader);
                 Iterator<RMIClassLoaderSpi> iter = loader.iterator();
-                RMIClassLoaderSpi firstSpi;
+                RMIClassLoaderSpi spi;
                 while ( iter.hasNext() ) {
                     try {
-                        firstSpi = iter.next();
-                        if (firstSpi != null) {
-                            if (providerClassName == null) {
-                                logger.log(Level.CONFIG, "loaded: {0}", firstSpi.getClass().getName());
-                                return firstSpi;
-                            }
-                            if (!providerClassName.equals(firstSpi.getClass().getName()))
+                        spi = iter.next();
+                        if (spi != null) {
+                            if (!name.equals(spi.getClass().getName()))
                                 continue;
-                            logger.log(Level.CONFIG, "loaded: {0}", providerClassName);
-                            return firstSpi;
+                            logger.log(Level.CONFIG, "loaded: {0}", name);
+                            return spi;
                         }
                     } catch (Exception e) {
                         logger.log( 
@@ -135,11 +166,40 @@ public final class ClassLoading {
                         );
                     }
                 }
-                if (providerClassName != null) logger.log(Level.CONFIG,
-                        "uable to find {0}" , providerClassName);
+                logger.log(Level.CONFIG, "uable to find {0}" , providerName);
                 return null;
             }
         });
+        if (newProvider != null) {
+            provider = newProvider;
+            return true;
+        } else if (providerName == null) {
+            provider = null;
+        }
+        return false;
+    }
+    
+    /**
+     * Installs a new RMIClassLoaderSpi provider with the ClassLoader 
+     * provided.
+     * 
+     * @param providerName fully defined class name of the provider, if null,
+     * a new provider instance will be determined by system properties.
+     * @param providerLoader The class loader to be used to load 
+     * provider-configuration files and provider classes, or null if the 
+     * system class loader (or, failing that, the bootstrap class loader) 
+     * is to be used.
+     * @return true if successful.
+     * @throws SecurityException if caller doesn't have RuntimePermission "getFactory"
+     */
+    public static boolean installNewProvider(
+            String providerName, 
+            ClassLoader providerLoader)
+    {
+        permission.checkGuard(null);
+        synchronized (lock){
+            return provider(providerName, providerLoader);
+        }
     }
     
     /**



Mime
View raw message