| 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