ReloadingClassLoader.java |
1 package gate.util; 2 3 /** 4 * A ClassLoader that supports class reloading. 5 * It maintains a list of URLs which are searched for classes not found in the 6 * system classloader. 7 * URLs can be loaded and unloaded. Loading the same URL twice will cause the 8 * jar file or directory pointed by the URL to be reloaded. 9 */ 10 11 import java.net.URL; 12 import java.net.URLClassLoader; 13 import java.util.*; 14 15 public class ReloadingClassLoader extends ClassLoader { 16 17 /** 18 * Constructs a ReloadingClassLoader using a custom class loader as parent. 19 * 20 * @param parent the parent class loader. The parent class loader should give 21 * access to the system classes at the least (in order to load a new class 22 * access to {@link java.lang.Object} is required). 23 */ 24 public ReloadingClassLoader(ClassLoader parent){ 25 this.parent = parent; 26 loaders = new HashMap(); 27 } 28 29 30 /** 31 * Constructs a ReloadingClassLoader using the System Class Loader as a 32 * parent. 33 */ 34 public ReloadingClassLoader() { 35 this(ClassLoader.getSystemClassLoader()); 36 } 37 38 /** 39 * Registers an URL as a location where class files can be found. 40 * If the URL was already registered the the classes found at the location 41 * will be reloaded. 42 * @param url the URL pointing to a jar file or to a directory containing 43 * class files. 44 */ 45 public void load(URL url){ 46 LocationClassLoader loader = new LocationClassLoader(url); 47 loaders.put(url, loader); 48 } 49 50 /** 51 * Removes a registered URL. 52 * @param url the URl to be unloaded. 53 */ 54 public void unload(URL url){ 55 loaders.remove(url); 56 } 57 58 /** 59 * Loads the class with the specified name. It searches for classes in the 60 * following order: 61 * <ol> 62 * <li>the parent classloader</li> 63 * <li>all the locations registered with this class loader</li> 64 * </ol> 65 * 66 * @param name The name of the class 67 * @param resolve If <tt>true</tt> then resolve the class 68 * @return The resulting <tt>Class</tt> object 69 * @throws ClassNotFoundException If the class could not be found 70 */ 71 protected synchronized Class loadClass(String name, boolean resolve) 72 throws ClassNotFoundException{ 73 Class c = null; 74 //check with the parent (most classes are fixed) 75 if(parent != null){ 76 try { 77 c = parent.loadClass(name); 78 }catch (ClassNotFoundException cnfe) {} 79 } 80 81 if(c == null){ 82 //Check all the loaders for the class 83 Iterator loaderIter = loaders.values().iterator(); 84 while (c == null && loaderIter.hasNext()) { 85 LocationClassLoader aLoader = (LocationClassLoader) loaderIter.next(); 86 try { 87 c = aLoader.loadClass(name, false); 88 } catch (ClassNotFoundException e) {} 89 } 90 } 91 if(c == null) throw new ClassNotFoundException(name); 92 if (resolve) resolveClass(c); 93 return c; 94 } 95 96 /** 97 * A ClassLoader that loads classes from a location specified by an URL. 98 */ 99 protected class LocationClassLoader extends URLClassLoader { 100 101 /** 102 * Constructs a LocationClassLoader for a specified URL. 103 * Uses the same parent classloader as the enclosing ReloadingClassLoader. 104 * @param location the URL to be searched for class files. 105 */ 106 public LocationClassLoader(URL location) { 107 super(new URL[]{location}, null); 108 this.location = location; 109 classCache = new HashMap(); 110 } 111 112 /** 113 * Loads the class with the specified name. It will search first the parent 114 * class loader, then an internal cache for classes already loaded and then 115 * the registered URL. 116 * 117 * @param name The name of the class 118 * @param resolve If <tt>true</tt> then resolve the class 119 * @return The resulting <tt>Class</tt> object 120 * 121 * @throws ClassNotFoundException If the class could not be found 122 */ 123 protected synchronized Class loadClass(String name, boolean resolve) 124 throws ClassNotFoundException{ 125 Class c = null; 126 //search the parent first 127 if(parent != null){ 128 try { 129 c = parent.loadClass(name); 130 }catch (ClassNotFoundException cnfe) {} 131 } 132 //search the cache 133 if(c == null){ 134 c = (Class) classCache.get(name); 135 } 136 //search the registered location 137 if (c == null) { 138 //this will trow ClassNotFoundException if necessary 139 c = findClass(name); 140 //save the class for future searches 141 classCache.put(name, c); 142 } 143 if (resolve) { 144 resolveClass(c); 145 } 146 return c; 147 } 148 149 /** 150 * A cache for classes already found and loaded. 151 */ 152 protected Map classCache; 153 /** 154 * The location to be searched for new classes. 155 */ 156 protected URL location; 157 }//protected class LocationClassLoader 158 159 160 /** 161 * Map that contains the {@link LocationClassLoader} for each registered URL. 162 */ 163 protected Map loaders; 164 165 /** 166 * The parent class loader. 167 */ 168 protected ClassLoader parent; 169 }