001: /*****************************************************************************
002: * *
003: * This file is part of the BeanShell Java Scripting distribution. *
004: * Documentation and updates may be found at http://www.beanshell.org/ *
005: * *
006: * Sun Public License Notice: *
007: * *
008: * The contents of this file are subject to the Sun Public License Version *
009: * 1.0 (the "License"); you may not use this file except in compliance with *
010: * the License. A copy of the License is available at http://www.sun.com *
011: * *
012: * The Original Code is BeanShell. The Initial Developer of the Original *
013: * Code is Pat Niemeyer. Portions created by Pat Niemeyer are Copyright *
014: * (C) 2000. All Rights Reserved. *
015: * *
016: * GNU Public License Notice: *
017: * *
018: * Alternatively, the contents of this file may be used under the terms of *
019: * the GNU Lesser General Public License (the "LGPL"), in which case the *
020: * provisions of LGPL are applicable instead of those above. If you wish to *
021: * allow use of your version of this file only under the terms of the LGPL *
022: * and not to allow others to use your version of this file under the SPL, *
023: * indicate your decision by deleting the provisions above and replace *
024: * them with the notice and other provisions required by the LGPL. If you *
025: * do not delete the provisions above, a recipient may use your version of *
026: * this file under either the SPL or the LGPL. *
027: * *
028: * Patrick Niemeyer (pat@pat.net) *
029: * Author of Learning Java, O'Reilly & Associates *
030: * http://www.pat.net/~pat/ *
031: * *
032: *****************************************************************************/package bsh.classpath;
033:
034: import java.net.*;
035: import java.util.*;
036: import java.io.*;
037: import bsh.BshClassManager;
038:
039: /**
040: One of the things BshClassLoader does is to address a deficiency in
041: URLClassLoader that prevents us from specifying individual classes
042: via URLs.
043: */
044: public class BshClassLoader extends URLClassLoader {
045: BshClassManager classManager;
046:
047: /**
048: @param bases URLs JARClassLoader seems to require absolute paths
049: */
050: public BshClassLoader(BshClassManager classManager, URL[] bases) {
051: super (bases);
052: this .classManager = classManager;
053: }
054:
055: /**
056: @param bases URLs JARClassLoader seems to require absolute paths
057: */
058: public BshClassLoader(BshClassManager classManager, BshClassPath bcp) {
059: this (classManager, bcp.getPathComponents());
060: }
061:
062: /**
063: For use by children
064: @param bases URLs JARClassLoader seems to require absolute paths
065: */
066: protected BshClassLoader(BshClassManager classManager) {
067: this (classManager, new URL[] {});
068: }
069:
070: // public version of addURL
071: public void addURL(URL url) {
072: super .addURL(url);
073: }
074:
075: /**
076: This modification allows us to reload classes which are in the
077: Java VM user classpath. We search first rather than delegate to
078: the parent classloader (or bootstrap path) first.
079:
080: An exception is for BeanShell core classes which are always loaded from
081: the same classloader as the interpreter.
082: */
083: public Class loadClass(String name, boolean resolve)
084: throws ClassNotFoundException {
085: Class c = null;
086:
087: /*
088: Check first for classes loaded through this loader.
089: The VM will not allow a class to be loaded twice.
090: */
091: c = findLoadedClass(name);
092: if (c != null)
093: return c;
094:
095: // This is copied from ClassManagerImpl
096: // We should refactor this somehow if it sticks around
097: if (name.startsWith(ClassManagerImpl.BSH_PACKAGE))
098: try {
099: return bsh.Interpreter.class.getClassLoader()
100: .loadClass(name);
101: } catch (ClassNotFoundException e) {
102: }
103:
104: /*
105: Try to find the class using our classloading mechanism.
106: Note: I wish we didn't have to catch the exception here... slow
107: */
108: try {
109: c = findClass(name);
110: } catch (ClassNotFoundException e) {
111: }
112:
113: if (c == null)
114: throw new ClassNotFoundException("here in loaClass");
115:
116: if (resolve)
117: resolveClass(c);
118:
119: return c;
120: }
121:
122: /**
123: Find the correct source for the class...
124:
125: Try designated loader if any
126: Try our URLClassLoader paths if any
127: Try base loader if any
128: Try system ???
129: */
130: // add some caching for not found classes?
131: protected Class findClass(String name)
132: throws ClassNotFoundException {
133: // Deal with this cast somehow... maybe have this class use
134: // ClassManagerImpl type directly.
135: // Don't add the method to BshClassManager... it's really an impl thing
136: ClassManagerImpl bcm = (ClassManagerImpl) getClassManager();
137:
138: // Should we try to load the class ourselves or delegate?
139: // look for overlay loader
140:
141: ClassLoader cl = bcm.getLoaderForClass(name);
142:
143: Class c;
144:
145: // If there is a designated loader and it's not us delegate to it
146: if (cl != null && cl != this )
147: try {
148: return cl.loadClass(name);
149: } catch (ClassNotFoundException e) {
150: throw new ClassNotFoundException(
151: "Designated loader could not find class: " + e);
152: }
153:
154: // Let URLClassLoader try any paths it may have
155: if (getURLs().length > 0)
156: try {
157: return super .findClass(name);
158: } catch (ClassNotFoundException e) {
159: //System.out.println(
160: // "base loader here caught class not found: "+name );
161: }
162:
163: // If there is a baseLoader and it's not us delegate to it
164: cl = bcm.getBaseLoader();
165:
166: if (cl != null && cl != this )
167: try {
168: return cl.loadClass(name);
169: } catch (ClassNotFoundException e) {
170: }
171:
172: // Try system loader
173: return bcm.plainClassForName(name);
174: }
175:
176: /*
177: The superclass does something like this
178:
179: c = findLoadedClass(name);
180: if null
181: try
182: if parent not null
183: c = parent.loadClass(name, false);
184: else
185: c = findBootstrapClass(name);
186: catch ClassNotFoundException
187: c = findClass(name);
188: */
189:
190: BshClassManager getClassManager() {
191: return classManager;
192: }
193:
194: }
|