GateClassLoader.java |
1 /* 2 * GateClassLoader.java 3 * 4 * Copyright (c) 1998-2005, The University of Sheffield. 5 * 6 * This file is part of GATE (see http://gate.ac.uk/), and is free 7 * software, licenced under the GNU Library General Public License, 8 * Version 2, June 1991 (in the distribution as file licence.html, 9 * and also available at http://gate.ac.uk/gate/licence.html). 10 * 11 * Kalina Bontcheva, 1998 12 * 13 * Revised by Hamish for 1.2 style and URL/Jar loading, June 2000 14 * 15 * $Id: GateClassLoader.java,v 1.14 2005/10/10 17:41:36 nirajaswani Exp $ 16 */ 17 18 package gate.util; 19 20 import java.net.URL; 21 import java.net.URLClassLoader; 22 23 /** GATE's class loader, which allows loading of classes over the net. 24 * A list of URLs is searched, which should point at .jar files or 25 * to directories containing class file hierarchies. 26 * The class loader is unusual in supporting reloading of classes, which 27 * is useful for CREOLE developers who want to recompile modules without 28 * relaunching GATE. 29 * The loader is also used for creating JAPE RHS action classes. 30 */ 31 public class GateClassLoader extends URLClassLoader { 32 33 /** Debug flag */ 34 private static final boolean DEBUG = false; 35 36 /** Default construction - use an empty URL list. */ 37 public GateClassLoader() { super(new URL[0]); } 38 39 /** Chaining constructor. */ 40 public GateClassLoader(ClassLoader parent) { super(new URL[0], parent); } 41 42 /** Default construction with URLs list. */ 43 public GateClassLoader(URL[] urls) { super(urls); } 44 45 /** Chaining constructor with URLs list. */ 46 public GateClassLoader(URL[] urls, ClassLoader parent) { 47 super(urls, parent); 48 } // Chaining constructor with URLs list. 49 50 /** Appends the specified URL to the list of URLs to search for classes 51 * and resources. 52 */ 53 public void addURL(URL url) { super.addURL(url); } 54 55 /** Delegate loading to the super class (loadClass has protected 56 * access there). 57 */ 58 public synchronized Class loadClass(String name, boolean resolve) 59 throws ClassNotFoundException { 60 return super.loadClass(name, resolve); 61 } // loadClass(name, resolve) 62 63 /** Forward a call to super.defineClass, which is protected and final 64 * in super. This is used by JAPE and the Jdk compiler class. 65 */ 66 public Class defineGateClass(String name, byte[] bytes, int offset, int len) 67 { 68 return super.defineClass(name, bytes, offset, len); 69 } // defineGateClass(name, bytes, offset, len); 70 71 /** Forward a call to super.resolveClass, which is protected and final 72 * in super. This is used by JAPE and the Jdk compiler class 73 */ 74 public void resolveGateClass(Class c) { super.resolveClass(c); } 75 76 /** 77 * Given a fully qualified class name, this method returns the instance of Class if it is already loaded using the ClassLoader 78 * or it returns null. 79 * @param name 80 * @return 81 */ 82 public Class findExistingClass(String name) { 83 return findLoadedClass(name); 84 } 85 86 /** Reload a class. This works on the assumption that all classes that 87 * we are asked to reload will have been loaded by a GateClassLoader 88 * and not the system class loader. If this is not the case, this 89 * method will simply return the previously loaded class (because of 90 * the delegation chaining model of class loaders in JDK1.2 and above). 91 * <P> 92 * The method works by avoiding the normal chaining behaviour of 93 * class loaders by creating a star-shaped group of parallel loaders. 94 * Each of these chains of the system class loader, but as long as 95 * the class that we wish to reload wan't loaded by the system loader, 96 * it will not be present in a new loader of this type. 97 * <P> 98 * An implication is that reloaded classes must always be instantiated 99 * via the class returned from this method. 100 */ 101 public Class reloadClass(String name) throws ClassNotFoundException { 102 Class theClass = null; 103 104 // if the class isn't already present in this class loader 105 // we can just load it 106 theClass = findLoadedClass(name); 107 if(theClass == null) 108 return loadClass(name); 109 110 // if there's a cached loader, try that 111 if(cachedReloader != null) { 112 113 // if the cached loader hasn't already loaded this file, then ask it to 114 theClass = cachedReloader.findLoadedClass(name); 115 if(theClass == null) 116 return cachedReloader.loadClass(name); 117 } 118 119 // create a new reloader and cache it 120 cachedReloader = new GateClassLoader(getURLs()); 121 122 // ask the new reloader to load the class 123 return cachedReloader.loadClass(name, true); 124 125 } // reloadClass(String name) 126 127 /** A cache used by the reloadClass method to store the last new 128 * loader that we created. 129 */ 130 private static GateClassLoader cachedReloader = null; 131 132 } // GateClassLoader 133