Source for java.rmi.server.RMIClassLoader

   1: /* RMIClassLoader.java --
   2:    Copyright (c) 1996, 1997, 1998, 1999, 2002, 2003, 2004
   3:    Free Software Foundation, Inc.
   4: 
   5: This file is part of GNU Classpath.
   6: 
   7: GNU Classpath is free software; you can redistribute it and/or modify
   8: it under the terms of the GNU General Public License as published by
   9: the Free Software Foundation; either version 2, or (at your option)
  10: any later version.
  11: 
  12: GNU Classpath is distributed in the hope that it will be useful, but
  13: WITHOUT ANY WARRANTY; without even the implied warranty of
  14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15: General Public License for more details.
  16: 
  17: You should have received a copy of the GNU General Public License
  18: along with GNU Classpath; see the file COPYING.  If not, write to the
  19: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  20: 02110-1301 USA.
  21: 
  22: Linking this library statically or dynamically with other modules is
  23: making a combined work based on this library.  Thus, the terms and
  24: conditions of the GNU General Public License cover the whole
  25: combination.
  26: 
  27: As a special exception, the copyright holders of this library give you
  28: permission to link this library with independent modules to produce an
  29: executable, regardless of the license terms of these independent
  30: modules, and to copy and distribute the resulting executable under
  31: terms of your choice, provided that you also meet, for each linked
  32: independent module, the terms and conditions of the license of that
  33: module.  An independent module is a module which is not derived from
  34: or based on this library.  If you modify this library, you may extend
  35: this exception to your version of the library, but you are not
  36: obligated to do so.  If you do not wish to do so, delete this
  37: exception statement from your version. */
  38: 
  39: package java.rmi.server;
  40: 
  41: import gnu.classpath.ServiceFactory;
  42: import gnu.classpath.SystemProperties;
  43: import gnu.java.rmi.server.RMIClassLoaderImpl;
  44: 
  45: import java.net.MalformedURLException;
  46: import java.net.URL;
  47: import java.util.Iterator;
  48: 
  49: /**
  50:  * This class provides a set of public static utility methods for supporting
  51:  * network-based class loading in RMI. These methods are called by RMI's
  52:  * internal marshal streams to implement the dynamic class loading of types for
  53:  * RMI parameters and return values.
  54:  * @since 1.1
  55:  */
  56: public class RMIClassLoader
  57: {
  58:   /**
  59:    * This class isn't intended to be instantiated.
  60:    */
  61:   private RMIClassLoader() {}
  62: 
  63:   /**
  64:    * @deprecated
  65:    */
  66:   public static Class<?> loadClass(String name)
  67:     throws MalformedURLException, ClassNotFoundException
  68:   {
  69:     return loadClass("", name);
  70:   }
  71: 
  72:   public static Class<?> loadClass(String codebase, String name)
  73:     throws MalformedURLException, ClassNotFoundException
  74:   {
  75:     RMIClassLoaderSpi spi = getProviderInstance();
  76:     if (spi == null)
  77:       spi = getDefaultProviderInstance(); 
  78:     return spi.loadClass(codebase, name, null);
  79:   }
  80: 
  81:   public static Class<?> loadClass(String codebase, String name,
  82:                                    ClassLoader defaultLoader)
  83:     throws MalformedURLException, ClassNotFoundException
  84:   {
  85:     RMIClassLoaderSpi spi = getProviderInstance();
  86:     if (spi == null)
  87:       spi = getDefaultProviderInstance(); 
  88:     return spi.loadClass(codebase, name, defaultLoader);
  89:   }
  90: 
  91:   public static Class<?> loadProxyClass (String codeBase, String[] interfaces,
  92:                                          ClassLoader defaultLoader)
  93:     throws MalformedURLException, ClassNotFoundException
  94:   {
  95:     RMIClassLoaderSpi spi = getProviderInstance();
  96:     if (spi == null)
  97:       spi = getDefaultProviderInstance();
  98:     return spi.loadProxyClass(codeBase, interfaces, defaultLoader);
  99:   }
 100: 
 101:   /**
 102:    * Loads a class from <code>codeBase</code>.
 103:    *
 104:    * This method delegates to
 105:    * {@link RMIClassLoaderSpi#loadClass(String, String, ClassLoader)} and
 106:    * passes <code>codeBase.toString()</code> as first argument,
 107:    * <code>name</code> as second argument and <code>null</code> as third
 108:    * argument.
 109:    *
 110:    * @param codeBase the code base from which to load the class
 111:    * @param name the name of the class
 112:    *
 113:    * @return the loaded class
 114:    *
 115:    * @throws MalformedURLException if the URL is not well formed
 116:    * @throws ClassNotFoundException if the requested class cannot be found
 117:    */
 118:   public static Class<?> loadClass(URL codeBase, String name)
 119:     throws MalformedURLException, ClassNotFoundException
 120:   {
 121:     RMIClassLoaderSpi spi = getProviderInstance();
 122:     if (spi == null)
 123:       spi = getDefaultProviderInstance(); 
 124:     return spi.loadClass(codeBase.toString(), name, null);
 125:   }
 126: 
 127:   /**
 128:    * Gets a classloader for the given codebase and with the current
 129:    * context classloader as parent.
 130:    * 
 131:    * @param codebase
 132:    * 
 133:    * @return a classloader for the given codebase
 134:    * 
 135:    * @throws MalformedURLException if the codebase contains a malformed URL
 136:    */
 137:   public static ClassLoader getClassLoader(String codebase) 
 138:     throws MalformedURLException
 139:   {
 140:     RMIClassLoaderSpi spi = getProviderInstance();
 141:     if (spi == null)
 142:       spi = getDefaultProviderInstance(); 
 143:     return spi.getClassLoader(codebase);
 144:   }
 145:  
 146:   /**
 147:    * Returns a string representation of the network location where a remote
 148:    * endpoint can get the class-definition of the given class.
 149:    *
 150:    * @param cl
 151:    *
 152:    * @return a space seperated list of URLs where the class-definition
 153:    * of cl may be found
 154:    */
 155:   public static String getClassAnnotation(Class<?> cl)
 156:   {
 157:     RMIClassLoaderSpi spi = getProviderInstance();
 158:     if (spi == null)
 159:       spi = getDefaultProviderInstance(); 
 160:     return spi.getClassAnnotation(cl);
 161:   }
 162: 
 163:   /**
 164:    * @deprecated
 165:    */
 166:   public static Object getSecurityContext (ClassLoader loader)
 167:   {
 168:     throw new Error ("Not implemented");
 169:   }
 170: 
 171:   /**
 172:    * Returns the default service provider for <code>RMIClassLoader</code>.
 173:    *
 174:    * @return the default provider for <code>RMIClassLoader</code>
 175:    */
 176:   public static RMIClassLoaderSpi getDefaultProviderInstance()
 177:   {
 178:     return RMIClassLoaderImpl.getInstance();
 179:   }
 180: 
 181:   /**
 182:    * Chooses, instantiates and returns a service provider.
 183:    *
 184:    * @return a service provider
 185:    */
 186:   private static RMIClassLoaderSpi getProviderInstance()
 187:   {
 188:     // If the user asked for the default, return it.  We do a special
 189:     // check here because our standard service lookup function does not
 190:     // handle this -- nor should it.
 191:     String prop = SystemProperties.getProperty("java.rmi.server.RMIClassLoaderSpi");
 192:     if ("default".equals(prop))
 193:       return null;
 194:     Iterator it = ServiceFactory.lookupProviders(RMIClassLoaderSpi.class,
 195:                                                  null);
 196:     if (it == null || ! it.hasNext())
 197:       return null;
 198:     // FIXME: the spec says we ought to throw an Error of some kind if
 199:     // the specified provider is not suitable for some reason.  However
 200:     // our service factory simply logs the problem and moves on to the next
 201:     // provider in this situation.
 202:     return (RMIClassLoaderSpi) it.next();
 203:   }
 204: }