| GateClassLoader.java |
1 /*
2 * GateClassLoader.java
3 *
4 * Copyright (c) 1998-2004, 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.11 2004/07/21 17:10:09 akshay 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 /** Reload a class. This works on the assumption that all classes that
77 * we are asked to reload will have been loaded by a GateClassLoader
78 * and not the system class loader. If this is not the case, this
79 * method will simply return the previously loaded class (because of
80 * the delegation chaining model of class loaders in JDK1.2 and above).
81 * <P>
82 * The method works by avoiding the normal chaining behaviour of
83 * class loaders by creating a star-shaped group of parallel loaders.
84 * Each of these chains of the system class loader, but as long as
85 * the class that we wish to reload wan't loaded by the system loader,
86 * it will not be present in a new loader of this type.
87 * <P>
88 * An implication is that reloaded classes must always be instantiated
89 * via the class returned from this method.
90 */
91 public Class reloadClass(String name) throws ClassNotFoundException {
92 Class theClass = null;
93
94 // if the class isn't already present in this class loader
95 // we can just load it
96 theClass = findLoadedClass(name);
97 if(theClass == null)
98 return loadClass(name);
99
100 // if there's a cached loader, try that
101 if(cachedReloader != null) {
102
103 // if the cached loader hasn't already loaded this file, then ask it to
104 theClass = cachedReloader.findLoadedClass(name);
105 if(theClass == null)
106 return cachedReloader.loadClass(name);
107 }
108
109 // create a new reloader and cache it
110 cachedReloader = new GateClassLoader(getURLs());
111
112 // ask the new reloader to load the class
113 return cachedReloader.loadClass(name, true);
114
115 } // reloadClass(String name)
116
117 /** A cache used by the reloadClass method to store the last new
118 * loader that we created.
119 */
120 private static GateClassLoader cachedReloader = null;
121
122 } // GateClassLoader
123