KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > AntClassLoader


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18
19 package org.apache.tools.ant;
20
21 import java.io.ByteArrayOutputStream JavaDoc;
22 import java.io.File JavaDoc;
23 import java.io.FileInputStream JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.io.InputStreamReader JavaDoc;
27 import java.io.Reader JavaDoc;
28 import java.lang.reflect.Constructor JavaDoc;
29 import java.net.MalformedURLException JavaDoc;
30 import java.net.URL JavaDoc;
31 import java.util.Collections JavaDoc;
32 import java.util.Enumeration JavaDoc;
33 import java.util.HashMap JavaDoc;
34 import java.util.Hashtable JavaDoc;
35 import java.util.Map JavaDoc;
36 import java.util.StringTokenizer JavaDoc;
37 import java.util.Vector JavaDoc;
38 import java.util.jar.Attributes JavaDoc;
39 import java.util.jar.Attributes.Name;
40 import java.util.jar.JarFile JavaDoc;
41 import java.util.jar.Manifest JavaDoc;
42 import java.util.zip.ZipEntry JavaDoc;
43 import java.util.zip.ZipFile JavaDoc;
44 import org.apache.tools.ant.types.Path;
45 import org.apache.tools.ant.util.CollectionUtils;
46 import org.apache.tools.ant.util.FileUtils;
47 import org.apache.tools.ant.util.JavaEnvUtils;
48 import org.apache.tools.ant.util.LoaderUtils;
49 import org.apache.tools.ant.launch.Locator;
50
51 /**
52  * Used to load classes within ant with a different classpath from
53  * that used to start ant. Note that it is possible to force a class
54  * into this loader even when that class is on the system classpath by
55  * using the forceLoadClass method. Any subsequent classes loaded by that
56  * class will then use this loader rather than the system class loader.
57  *
58  * <p>
59  * Note that this classloader has a feature to allow loading
60  * in reverse order and for "isolation".
61  * Due to the fact that a number of
62  * methods in java.lang.ClassLoader are final (at least
63  * in java 1.4 getResources) this means that the
64  * class has to fake the given parent.
65  * </p>
66  *
67  */

68 public class AntClassLoader extends ClassLoader JavaDoc implements SubBuildListener {
69
70     private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
71
72     /**
73      * An enumeration of all resources of a given name found within the
74      * classpath of this class loader. This enumeration is used by the
75      * ClassLoader.findResources method, which is in
76      * turn used by the ClassLoader.getResources method.
77      *
78      * @see AntClassLoader#findResources(String)
79      * @see java.lang.ClassLoader#getResources(String)
80      */

81     private class ResourceEnumeration implements Enumeration JavaDoc {
82         /**
83          * The name of the resource being searched for.
84          */

85         private String JavaDoc resourceName;
86
87         /**
88          * The index of the next classpath element to search.
89          */

90         private int pathElementsIndex;
91
92         /**
93          * The URL of the next resource to return in the enumeration. If this
94          * field is <code>null</code> then the enumeration has been completed,
95          * i.e., there are no more elements to return.
96          */

97         private URL JavaDoc nextResource;
98
99         /**
100          * Constructs a new enumeration of resources of the given name found
101          * within this class loader's classpath.
102          *
103          * @param name the name of the resource to search for.
104          */

105         ResourceEnumeration(String JavaDoc name) {
106             this.resourceName = name;
107             this.pathElementsIndex = 0;
108             findNextResource();
109         }
110
111         /**
112          * Indicates whether there are more elements in the enumeration to
113          * return.
114          *
115          * @return <code>true</code> if there are more elements in the
116          * enumeration; <code>false</code> otherwise.
117          */

118         public boolean hasMoreElements() {
119             return (this.nextResource != null);
120         }
121
122         /**
123          * Returns the next resource in the enumeration.
124          *
125          * @return the next resource in the enumeration
126          */

127         public Object JavaDoc nextElement() {
128             URL JavaDoc ret = this.nextResource;
129             findNextResource();
130             return ret;
131         }
132
133         /**
134          * Locates the next resource of the correct name in the classpath and
135          * sets <code>nextResource</code> to the URL of that resource. If no
136          * more resources can be found, <code>nextResource</code> is set to
137          * <code>null</code>.
138          */

139         private void findNextResource() {
140             URL JavaDoc url = null;
141             while ((pathElementsIndex < pathComponents.size())
142                    && (url == null)) {
143                 try {
144                     File JavaDoc pathComponent
145                         = (File JavaDoc) pathComponents.elementAt(pathElementsIndex);
146                     url = getResourceURL(pathComponent, this.resourceName);
147                     pathElementsIndex++;
148                 } catch (BuildException e) {
149                     // ignore path elements which are not valid relative to the
150
// project
151
}
152             }
153             this.nextResource = url;
154         }
155     }
156
157     /**
158      * The size of buffers to be used in this classloader.
159      */

160     private static final int BUFFER_SIZE = 8192;
161     /**
162      * Number of array elements in a test array of strings
163      */

164     private static final int NUMBER_OF_STRINGS = 256;
165
166     /**
167      * The components of the classpath that the classloader searches
168      * for classes.
169      */

170     private Vector JavaDoc pathComponents = new Vector JavaDoc();
171
172     /**
173      * The project to which this class loader belongs.
174      */

175     private Project project;
176
177     /**
178      * Indicates whether the parent class loader should be
179      * consulted before trying to load with this class loader.
180      */

181     private boolean parentFirst = true;
182
183     /**
184      * These are the package roots that are to be loaded by the parent class
185      * loader regardless of whether the parent class loader is being searched
186      * first or not.
187      */

188     private Vector JavaDoc systemPackages = new Vector JavaDoc();
189
190     /**
191      * These are the package roots that are to be loaded by this class loader
192      * regardless of whether the parent class loader is being searched first
193      * or not.
194      */

195     private Vector JavaDoc loaderPackages = new Vector JavaDoc();
196
197     /**
198      * Whether or not this classloader will ignore the base
199      * classloader if it can't find a class.
200      *
201      * @see #setIsolated(boolean)
202      */

203     private boolean ignoreBase = false;
204
205     /**
206      * The parent class loader, if one is given or can be determined.
207      */

208     private ClassLoader JavaDoc parent = null;
209
210     /**
211      * A hashtable of zip files opened by the classloader (File to ZipFile).
212      */

213     private Hashtable JavaDoc zipFiles = new Hashtable JavaDoc();
214
215     /** Static map of jar file/time to manifiest class-path entries */
216     private static Map JavaDoc/*<String,String>*/ pathMap = Collections.synchronizedMap(new HashMap JavaDoc());
217
218     /**
219      * The context loader saved when setting the thread's current
220      * context loader.
221      */

222     private ClassLoader JavaDoc savedContextLoader = null;
223     /**
224      * Whether or not the context loader is currently saved.
225      */

226     private boolean isContextLoaderSaved = false;
227
228     /**
229      * Create an Ant ClassLoader for a given project, with
230      * a parent classloader and an initial classpath.
231      * @since Ant 1.7.
232      * @param parent the parent for this classloader.
233      * @param project The project to which this classloader is to
234      * belong.
235      * @param classpath The classpath to use to load classes.
236      */

237     public AntClassLoader(
238         ClassLoader JavaDoc parent, Project project, Path classpath) {
239         setParent(parent);
240         setClassPath(classpath);
241         setProject(project);
242     }
243
244     /**
245      * Create an Ant Class Loader
246      */

247     public AntClassLoader() {
248         setParent(null);
249     }
250
251     /**
252      * Creates a classloader for the given project using the classpath given.
253      *
254      * @param project The project to which this classloader is to belong.
255      * Must not be <code>null</code>.
256      * @param classpath The classpath to use to load the classes. This
257      * is combined with the system classpath in a manner
258      * determined by the value of ${build.sysclasspath}.
259      * May be <code>null</code>, in which case no path
260      * elements are set up to start with.
261      */

262     public AntClassLoader(Project project, Path classpath) {
263         setParent(null);
264         setProject(project);
265         setClassPath(classpath);
266     }
267
268     /**
269      * Creates a classloader for the given project using the classpath given.
270      *
271      * @param parent The parent classloader to which unsatisfied loading
272      * attempts are delegated. May be <code>null</code>,
273      * in which case the classloader which loaded this
274      * class is used as the parent.
275      * @param project The project to which this classloader is to belong.
276      * Must not be <code>null</code>.
277      * @param classpath the classpath to use to load the classes.
278      * May be <code>null</code>, in which case no path
279      * elements are set up to start with.
280      * @param parentFirst If <code>true</code>, indicates that the parent
281      * classloader should be consulted before trying to
282      * load the a class through this loader.
283      */

284     public AntClassLoader(ClassLoader JavaDoc parent, Project project, Path classpath,
285                           boolean parentFirst) {
286         this(project, classpath);
287         if (parent != null) {
288             setParent(parent);
289         }
290         setParentFirst(parentFirst);
291         addJavaLibraries();
292     }
293
294
295     /**
296      * Creates a classloader for the given project using the classpath given.
297      *
298      * @param project The project to which this classloader is to belong.
299      * Must not be <code>null</code>.
300      * @param classpath The classpath to use to load the classes. May be
301      * <code>null</code>, in which case no path
302      * elements are set up to start with.
303      * @param parentFirst If <code>true</code>, indicates that the parent
304      * classloader should be consulted before trying to
305      * load the a class through this loader.
306      */

307     public AntClassLoader(Project project, Path classpath,
308                           boolean parentFirst) {
309         this(null, project, classpath, parentFirst);
310     }
311
312     /**
313      * Creates an empty class loader. The classloader should be configured
314      * with path elements to specify where the loader is to look for
315      * classes.
316      *
317      * @param parent The parent classloader to which unsatisfied loading
318      * attempts are delegated. May be <code>null</code>,
319      * in which case the classloader which loaded this
320      * class is used as the parent.
321      * @param parentFirst If <code>true</code>, indicates that the parent
322      * classloader should be consulted before trying to
323      * load the a class through this loader.
324      */

325     public AntClassLoader(ClassLoader JavaDoc parent, boolean parentFirst) {
326         setParent(parent);
327         project = null;
328         this.parentFirst = parentFirst;
329     }
330
331     /**
332      * Set the project associated with this class loader
333      *
334      * @param project the project instance
335      */

336     public void setProject(Project project) {
337         this.project = project;
338         if (project != null) {
339             project.addBuildListener(this);
340         }
341     }
342
343     /**
344      * Set the classpath to search for classes to load. This should not be
345      * changed once the classloader starts to server classes
346      *
347      * @param classpath the search classpath consisting of directories and
348      * jar/zip files.
349      */

350     public void setClassPath(Path classpath) {
351         pathComponents.removeAllElements();
352         if (classpath != null) {
353             Path actualClasspath = classpath.concatSystemClasspath("ignore");
354             String JavaDoc[] pathElements = actualClasspath.list();
355             for (int i = 0; i < pathElements.length; ++i) {
356                 try {
357                     addPathElement(pathElements[i]);
358                 } catch (BuildException e) {
359                     // ignore path elements which are invalid
360
// relative to the project
361
}
362             }
363         }
364     }
365
366     /**
367      * Set the parent for this class loader. This is the class loader to which
368      * this class loader will delegate to load classes
369      *
370      * @param parent the parent class loader.
371      */

372     public void setParent(ClassLoader JavaDoc parent) {
373         if (parent == null) {
374             this.parent = AntClassLoader.class.getClassLoader();
375         } else {
376             this.parent = parent;
377         }
378     }
379
380     /**
381      * Control whether class lookup is delegated to the parent loader first
382      * or after this loader. Use with extreme caution. Setting this to
383      * false violates the class loader hierarchy and can lead to Linkage errors
384      *
385      * @param parentFirst if true, delegate initial class search to the parent
386      * classloader.
387      */

388     public void setParentFirst(boolean parentFirst) {
389         this.parentFirst = parentFirst;
390     }
391
392
393     /**
394      * Logs a message through the project object if one has been provided.
395      *
396      * @param message The message to log.
397      * Should not be <code>null</code>.
398      *
399      * @param priority The logging priority of the message.
400      */

401     protected void log(String JavaDoc message, int priority) {
402         if (project != null) {
403             project.log(message, priority);
404         }
405         // else {
406
// System.out.println(message);
407
// }
408
}
409
410     /**
411      * Sets the current thread's context loader to this classloader, storing
412      * the current loader value for later resetting.
413      */

414     public void setThreadContextLoader() {
415         if (isContextLoaderSaved) {
416             throw new BuildException("Context loader has not been reset");
417         }
418         if (LoaderUtils.isContextLoaderAvailable()) {
419             savedContextLoader = LoaderUtils.getContextClassLoader();
420             ClassLoader JavaDoc loader = this;
421             if (project != null
422                 && "only".equals(project.getProperty("build.sysclasspath"))) {
423                 loader = this.getClass().getClassLoader();
424             }
425             LoaderUtils.setContextClassLoader(loader);
426             isContextLoaderSaved = true;
427         }
428     }
429
430     /**
431      * Resets the current thread's context loader to its original value.
432      */

433     public void resetThreadContextLoader() {
434         if (LoaderUtils.isContextLoaderAvailable()
435             && isContextLoaderSaved) {
436             LoaderUtils.setContextClassLoader(savedContextLoader);
437             savedContextLoader = null;
438             isContextLoaderSaved = false;
439         }
440     }
441
442
443     /**
444      * Adds an element to the classpath to be searched.
445      *
446      * @param pathElement The path element to add. Must not be
447      * <code>null</code>.
448      *
449      * @exception BuildException if the given path element cannot be resolved
450      * against the project.
451      */

452     public void addPathElement(String JavaDoc pathElement) throws BuildException {
453         File JavaDoc pathComponent
454             = project != null ? project.resolveFile(pathElement)
455             : new File JavaDoc(pathElement);
456         try {
457             addPathFile(pathComponent);
458         } catch (IOException JavaDoc e) {
459             throw new BuildException(e);
460         }
461     }
462
463     /**
464      * Add a file to the path.
465      * Reads the manifest, if available, and adds any additional class path jars
466      * specified in the manifest.
467      *
468      * @param pathComponent the file which is to be added to the path for
469      * this class loader
470      *
471      * @throws IOException if data needed from the file cannot be read.
472      */

473     protected void addPathFile(File JavaDoc pathComponent) throws IOException JavaDoc {
474         pathComponents.addElement(pathComponent);
475         if (pathComponent.isDirectory()) {
476             return;
477         }
478
479         String JavaDoc absPathPlusTimeAndLength =
480             pathComponent.getAbsolutePath() + pathComponent.lastModified() + "-"
481             + pathComponent.length();
482         String JavaDoc classpath = (String JavaDoc) pathMap.get(absPathPlusTimeAndLength);
483         if (classpath == null) {
484             ZipFile JavaDoc jarFile = null;
485             InputStream JavaDoc manifestStream = null;
486             try {
487                 jarFile = new ZipFile JavaDoc(pathComponent);
488                 manifestStream
489                     = jarFile.getInputStream(new ZipEntry JavaDoc("META-INF/MANIFEST.MF"));
490
491                 if (manifestStream == null) {
492                     return;
493                 }
494                 Reader JavaDoc manifestReader
495                     = new InputStreamReader JavaDoc(manifestStream, "UTF-8");
496                 org.apache.tools.ant.taskdefs.Manifest manifest
497                     = new org.apache.tools.ant.taskdefs.Manifest(manifestReader);
498                 classpath
499                     = manifest.getMainSection().getAttributeValue("Class-Path");
500
501             } catch (org.apache.tools.ant.taskdefs.ManifestException e) {
502                 // ignore
503
} finally {
504                 if (manifestStream != null) {
505                     manifestStream.close();
506                 }
507                 if (jarFile != null) {
508                     jarFile.close();
509                 }
510             }
511             if (classpath == null) {
512                 classpath = "";
513             }
514             pathMap.put(absPathPlusTimeAndLength, classpath);
515         }
516
517         if (!"".equals(classpath)) {
518             URL JavaDoc baseURL = FILE_UTILS.getFileURL(pathComponent);
519             StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(classpath);
520             while (st.hasMoreTokens()) {
521                 String JavaDoc classpathElement = st.nextToken();
522                 URL JavaDoc libraryURL = new URL JavaDoc(baseURL, classpathElement);
523                 if (!libraryURL.getProtocol().equals("file")) {
524                     log("Skipping jar library " + classpathElement
525                         + " since only relative URLs are supported by this"
526                         + " loader", Project.MSG_VERBOSE);
527                     continue;
528                 }
529                 String JavaDoc decodedPath = Locator.decodeUri(libraryURL.getFile());
530                 File JavaDoc libraryFile = new File JavaDoc(decodedPath);
531                 if (libraryFile.exists() && !isInPath(libraryFile)) {
532                     addPathFile(libraryFile);
533                 }
534             }
535         }
536     }
537
538     /**
539      * Returns the classpath this classloader will consult.
540      *
541      * @return the classpath used for this classloader, with elements
542      * separated by the path separator for the system.
543      */

544     public String JavaDoc getClasspath() {
545         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
546         boolean firstPass = true;
547         Enumeration JavaDoc componentEnum = pathComponents.elements();
548         while (componentEnum.hasMoreElements()) {
549             if (!firstPass) {
550                 sb.append(System.getProperty("path.separator"));
551             } else {
552                 firstPass = false;
553             }
554             sb.append(((File JavaDoc) componentEnum.nextElement()).getAbsolutePath());
555         }
556         return sb.toString();
557     }
558
559     /**
560      * Sets whether this classloader should run in isolated mode. In
561      * isolated mode, classes not found on the given classpath will
562      * not be referred to the parent class loader but will cause a
563      * ClassNotFoundException.
564      *
565      * @param isolated Whether or not this classloader should run in
566      * isolated mode.
567      */

568     public synchronized void setIsolated(boolean isolated) {
569         ignoreBase = isolated;
570     }
571
572     /**
573      * Forces initialization of a class in a JDK 1.1 compatible, albeit hacky
574      * way.
575      *
576      * @param theClass The class to initialize.
577      * Must not be <code>null</code>.
578      *
579      * @deprecated since 1.6.x.
580      * Use Class.forName with initialize=true instead.
581      */

582     public static void initializeClass(Class JavaDoc theClass) {
583         // ***HACK*** We ask the VM to create an instance
584
// by voluntarily providing illegal arguments to force
585
// the VM to run the class' static initializer, while
586
// at the same time not running a valid constructor.
587

588         final Constructor JavaDoc[] cons = theClass.getDeclaredConstructors();
589         //At least one constructor is guaranteed to be there, but check anyway.
590
if (cons != null) {
591             if (cons.length > 0 && cons[0] != null) {
592                 final String JavaDoc[] strs = new String JavaDoc[NUMBER_OF_STRINGS];
593                 try {
594                     cons[0].newInstance((Object JavaDoc[]) strs);
595                     // Expecting an exception to be thrown by this call:
596
// IllegalArgumentException: wrong number of Arguments
597
} catch (Exception JavaDoc e) {
598                     // Ignore - we are interested only in the side
599
// effect - that of getting the static initializers
600
// invoked. As we do not want to call a valid
601
// constructor to get this side effect, an
602
// attempt is made to call a hopefully
603
// invalid constructor - come on, nobody
604
// would have a constructor that takes in
605
// 256 String arguments ;-)
606
// (In fact, they can't - according to JVM spec
607
// section 4.10, the number of method parameters is limited
608
// to 255 by the definition of a method descriptor.
609
// Constructors count as methods here.)
610
}
611             }
612         }
613     }
614
615     /**
616      * Adds a package root to the list of packages which must be loaded on the
617      * parent loader.
618      *
619      * All subpackages are also included.
620      *
621      * @param packageRoot The root of all packages to be included.
622      * Should not be <code>null</code>.
623      */

624     public void addSystemPackageRoot(String JavaDoc packageRoot) {
625         systemPackages.addElement(packageRoot
626                                   + (packageRoot.endsWith(".") ? "" : "."));
627     }
628
629     /**
630      * Adds a package root to the list of packages which must be loaded using
631      * this loader.
632      *
633      * All subpackages are also included.
634      *
635      * @param packageRoot The root of all packages to be included.
636      * Should not be <code>null</code>.
637      */

638     public void addLoaderPackageRoot(String JavaDoc packageRoot) {
639         loaderPackages.addElement(packageRoot
640                                   + (packageRoot.endsWith(".") ? "" : "."));
641     }
642
643     /**
644      * Loads a class through this class loader even if that class is available
645      * on the parent classpath.
646      *
647      * This ensures that any classes which are loaded by the returned class
648      * will use this classloader.
649      *
650      * @param classname The name of the class to be loaded.
651      * Must not be <code>null</code>.
652      *
653      * @return the required Class object
654      *
655      * @exception ClassNotFoundException if the requested class does not exist
656      * on this loader's classpath.
657      */

658     public Class JavaDoc forceLoadClass(String JavaDoc classname)
659         throws ClassNotFoundException JavaDoc {
660         log("force loading " + classname, Project.MSG_DEBUG);
661
662         Class JavaDoc theClass = findLoadedClass(classname);
663
664         if (theClass == null) {
665             theClass = findClass(classname);
666         }
667
668         return theClass;
669     }
670
671     /**
672      * Loads a class through this class loader but defer to the parent class
673      * loader.
674      *
675      * This ensures that instances of the returned class will be compatible
676      * with instances which have already been loaded on the parent
677      * loader.
678      *
679      * @param classname The name of the class to be loaded.
680      * Must not be <code>null</code>.
681      *
682      * @return the required Class object
683      *
684      * @exception ClassNotFoundException if the requested class does not exist
685      * on this loader's classpath.
686      */

687     public Class JavaDoc forceLoadSystemClass(String JavaDoc classname)
688         throws ClassNotFoundException JavaDoc {
689         log("force system loading " + classname, Project.MSG_DEBUG);
690
691         Class JavaDoc theClass = findLoadedClass(classname);
692
693         if (theClass == null) {
694             theClass = findBaseClass(classname);
695         }
696
697         return theClass;
698     }
699
700     /**
701      * Returns a stream to read the requested resource name.
702      *
703      * @param name The name of the resource for which a stream is required.
704      * Must not be <code>null</code>.
705      *
706      * @return a stream to the required resource or <code>null</code> if the
707      * resource cannot be found on the loader's classpath.
708      */

709     public InputStream JavaDoc getResourceAsStream(String JavaDoc name) {
710
711         InputStream JavaDoc resourceStream = null;
712         if (isParentFirst(name)) {
713             resourceStream = loadBaseResource(name);
714             if (resourceStream != null) {
715                 log("ResourceStream for " + name
716                     + " loaded from parent loader", Project.MSG_DEBUG);
717
718             } else {
719                 resourceStream = loadResource(name);
720                 if (resourceStream != null) {
721                     log("ResourceStream for " + name
722                         + " loaded from ant loader", Project.MSG_DEBUG);
723                 }
724             }
725         } else {
726             resourceStream = loadResource(name);
727             if (resourceStream != null) {
728                 log("ResourceStream for " + name
729                     + " loaded from ant loader", Project.MSG_DEBUG);
730
731             } else {
732                 resourceStream = loadBaseResource(name);
733                 if (resourceStream != null) {
734                     log("ResourceStream for " + name
735                         + " loaded from parent loader", Project.MSG_DEBUG);
736                 }
737             }
738         }
739
740         if (resourceStream == null) {
741             log("Couldn't load ResourceStream for " + name,
742                 Project.MSG_DEBUG);
743         }
744
745         return resourceStream;
746     }
747
748     /**
749      * Returns a stream to read the requested resource name from this loader.
750      *
751      * @param name The name of the resource for which a stream is required.
752      * Must not be <code>null</code>.
753      *
754      * @return a stream to the required resource or <code>null</code> if
755      * the resource cannot be found on the loader's classpath.
756      */

757     private InputStream JavaDoc loadResource(String JavaDoc name) {
758         // we need to search the components of the path to see if we can
759
// find the class we want.
760
InputStream JavaDoc stream = null;
761
762         Enumeration JavaDoc e = pathComponents.elements();
763         while (e.hasMoreElements() && stream == null) {
764             File JavaDoc pathComponent = (File JavaDoc) e.nextElement();
765             stream = getResourceStream(pathComponent, name);
766         }
767         return stream;
768     }
769
770     /**
771      * Finds a system resource (which should be loaded from the parent
772      * classloader).
773      *
774      * @param name The name of the system resource to load.
775      * Must not be <code>null</code>.
776      *
777      * @return a stream to the named resource, or <code>null</code> if
778      * the resource cannot be found.
779      */

780     private InputStream JavaDoc loadBaseResource(String JavaDoc name) {
781         if (parent == null) {
782             return getSystemResourceAsStream(name);
783         } else {
784             return parent.getResourceAsStream(name);
785         }
786     }
787
788     /**
789      * Returns an inputstream to a given resource in the given file which may
790      * either be a directory or a zip file.
791      *
792      * @param file the file (directory or jar) in which to search for the
793      * resource. Must not be <code>null</code>.
794      * @param resourceName The name of the resource for which a stream is
795      * required. Must not be <code>null</code>.
796      *
797      * @return a stream to the required resource or <code>null</code> if
798      * the resource cannot be found in the given file.
799      */

800     private InputStream JavaDoc getResourceStream(File JavaDoc file, String JavaDoc resourceName) {
801         try {
802             if (!file.exists()) {
803                 return null;
804             }
805
806             if (file.isDirectory()) {
807                 File JavaDoc resource = new File JavaDoc(file, resourceName);
808
809                 if (resource.exists()) {
810                     return new FileInputStream JavaDoc(resource);
811                 }
812             } else {
813                 // is the zip file in the cache
814
ZipFile JavaDoc zipFile = (ZipFile JavaDoc) zipFiles.get(file);
815                 if (zipFile == null) {
816                     zipFile = new ZipFile JavaDoc(file);
817                     zipFiles.put(file, zipFile);
818                 }
819                 ZipEntry JavaDoc entry = zipFile.getEntry(resourceName);
820                 if (entry != null) {
821                     return zipFile.getInputStream(entry);
822                 }
823             }
824         } catch (Exception JavaDoc e) {
825             log("Ignoring Exception " + e.getClass().getName()
826                 + ": " + e.getMessage() + " reading resource " + resourceName
827                 + " from " + file, Project.MSG_VERBOSE);
828         }
829
830         return null;
831     }
832
833     /**
834      * Tests whether or not the parent classloader should be checked for
835      * a resource before this one. If the resource matches both the
836      * "use parent classloader first" and the "use this classloader first"
837      * lists, the latter takes priority.
838      *
839      * @param resourceName The name of the resource to check.
840      * Must not be <code>null</code>.
841      *
842      * @return whether or not the parent classloader should be checked for a
843      * resource before this one is.
844      */

845     private boolean isParentFirst(String JavaDoc resourceName) {
846         // default to the global setting and then see
847
// if this class belongs to a package which has been
848
// designated to use a specific loader first
849
// (this one or the parent one)
850

851         // XXX - shouldn't this always return false in isolated mode?
852

853         boolean useParentFirst = parentFirst;
854
855         for (Enumeration JavaDoc e = systemPackages.elements(); e.hasMoreElements();) {
856             String JavaDoc packageName = (String JavaDoc) e.nextElement();
857             if (resourceName.startsWith(packageName)) {
858                 useParentFirst = true;
859                 break;
860             }
861         }
862
863         for (Enumeration JavaDoc e = loaderPackages.elements(); e.hasMoreElements();) {
864             String JavaDoc packageName = (String JavaDoc) e.nextElement();
865             if (resourceName.startsWith(packageName)) {
866                 useParentFirst = false;
867                 break;
868             }
869         }
870
871         return useParentFirst;
872     }
873
874     /**
875      * Used for isolated resource seaching.
876      * @return the root classloader of AntClassLoader.
877      */

878     private ClassLoader JavaDoc getRootLoader() {
879         ClassLoader JavaDoc ret = getClass().getClassLoader();
880         while (ret != null && ret.getParent() != null) {
881             ret = ret.getParent();
882         }
883         return ret;
884     }
885
886     /**
887      * Finds the resource with the given name. A resource is
888      * some data (images, audio, text, etc) that can be accessed by class
889      * code in a way that is independent of the location of the code.
890      *
891      * @param name The name of the resource for which a stream is required.
892      * Must not be <code>null</code>.
893      *
894      * @return a URL for reading the resource, or <code>null</code> if the
895      * resource could not be found or the caller doesn't have
896      * adequate privileges to get the resource.
897      */

898     public URL JavaDoc getResource(String JavaDoc name) {
899         // we need to search the components of the path to see if
900
// we can find the class we want.
901
URL JavaDoc url = null;
902         if (isParentFirst(name)) {
903             url = (parent == null) ? super.getResource(name)
904                 : parent.getResource(name);
905         }
906
907         if (url != null) {
908             log("Resource " + name + " loaded from parent loader",
909                 Project.MSG_DEBUG);
910
911         } else {
912             // try and load from this loader if the parent either didn't find
913
// it or wasn't consulted.
914
Enumeration JavaDoc e = pathComponents.elements();
915             while (e.hasMoreElements() && url == null) {
916                 File JavaDoc pathComponent = (File JavaDoc) e.nextElement();
917                 url = getResourceURL(pathComponent, name);
918                 if (url != null) {
919                     log("Resource " + name
920                         + " loaded from ant loader",
921                         Project.MSG_DEBUG);
922                 }
923             }
924         }
925
926         if (url == null && !isParentFirst(name)) {
927             // this loader was first but it didn't find it - try the parent
928
if (ignoreBase) {
929                 url = (getRootLoader() == null) ? null
930                     : getRootLoader().getResource(name);
931             } else {
932                 url = (parent == null) ? super.getResource(name)
933                     : parent.getResource(name);
934             }
935             if (url != null) {
936                 log("Resource " + name + " loaded from parent loader",
937                     Project.MSG_DEBUG);
938             }
939         }
940
941         if (url == null) {
942             log("Couldn't load Resource " + name, Project.MSG_DEBUG);
943         }
944
945         return url;
946     }
947
948     /**
949      * Returns an enumeration of URLs representing all the resources with the
950      * given name by searching the class loader's classpath.
951      *
952      * @param name The resource name to search for.
953      * Must not be <code>null</code>.
954      * @return an enumeration of URLs for the resources
955      * @exception IOException if I/O errors occurs (can't happen)
956      */

957     protected Enumeration JavaDoc/*<URL>*/ findResources(String JavaDoc name) throws IOException JavaDoc {
958         Enumeration JavaDoc/*<URL>*/ mine = new ResourceEnumeration(name);
959         Enumeration JavaDoc/*<URL>*/ base;
960         if (parent != null && parent != getParent()) {
961             // Delegate to the parent:
962
base = parent.getResources(name);
963             // Note: could cause overlaps in case ClassLoader.this.parent has matches.
964
} else {
965             // ClassLoader.this.parent is already delegated to from
966
// ClassLoader.getResources, no need:
967
base = new CollectionUtils.EmptyEnumeration();
968         }
969         if (isParentFirst(name)) {
970             // Normal case.
971
return CollectionUtils.append(base, mine);
972         } else if (ignoreBase) {
973             return getRootLoader() == null
974                 ? mine
975                 : CollectionUtils.append(
976                     mine, getRootLoader().getResources(name));
977         } else {
978             // Inverted.
979
return CollectionUtils.append(mine, base);
980         }
981     }
982
983     /**
984      * Returns the URL of a given resource in the given file which may
985      * either be a directory or a zip file.
986      *
987      * @param file The file (directory or jar) in which to search for
988      * the resource. Must not be <code>null</code>.
989      * @param resourceName The name of the resource for which a stream
990      * is required. Must not be <code>null</code>.
991      *
992      * @return a stream to the required resource or <code>null</code> if the
993      * resource cannot be found in the given file object.
994      */

995     protected URL JavaDoc getResourceURL(File JavaDoc file, String JavaDoc resourceName) {
996         try {
997             if (!file.exists()) {
998                 return null;
999             }
1000
1001            if (file.isDirectory()) {
1002                File JavaDoc resource = new File JavaDoc(file, resourceName);
1003
1004                if (resource.exists()) {
1005                    try {
1006                        return FILE_UTILS.getFileURL(resource);
1007                    } catch (MalformedURLException JavaDoc ex) {
1008                        return null;
1009                    }
1010                }
1011            } else {
1012                ZipFile JavaDoc zipFile = (ZipFile JavaDoc) zipFiles.get(file);
1013                if (zipFile == null) {
1014                    zipFile = new ZipFile JavaDoc(file);
1015                    zipFiles.put(file, zipFile);
1016                }
1017
1018                ZipEntry JavaDoc entry = zipFile.getEntry(resourceName);
1019                if (entry != null) {
1020                    try {
1021                        return new URL JavaDoc("jar:" + FILE_UTILS.getFileURL(file)
1022                                       + "!/" + entry);
1023                    } catch (MalformedURLException JavaDoc ex) {
1024                        return null;
1025                    }
1026                }
1027            }
1028        } catch (Exception JavaDoc e) {
1029            e.printStackTrace();
1030        }
1031
1032        return null;
1033    }
1034
1035    /**
1036     * Loads a class with this class loader.
1037     *
1038     * This class attempts to load the class in an order determined by whether
1039     * or not the class matches the system/loader package lists, with the
1040     * loader package list taking priority. If the classloader is in isolated
1041     * mode, failure to load the class in this loader will result in a
1042     * ClassNotFoundException.
1043     *
1044     * @param classname The name of the class to be loaded.
1045     * Must not be <code>null</code>.
1046     * @param resolve <code>true</code> if all classes upon which this class
1047     * depends are to be loaded.
1048     *
1049     * @return the required Class object
1050     *
1051     * @exception ClassNotFoundException if the requested class does not exist
1052     * on the system classpath (when not in isolated mode) or this loader's
1053     * classpath.
1054     */

1055    protected synchronized Class JavaDoc loadClass(String JavaDoc classname, boolean resolve)
1056        throws ClassNotFoundException JavaDoc {
1057        // 'sync' is needed - otherwise 2 threads can load the same class
1058
// twice, resulting in LinkageError: duplicated class definition.
1059
// findLoadedClass avoids that, but without sync it won't work.
1060

1061        Class JavaDoc theClass = findLoadedClass(classname);
1062        if (theClass != null) {
1063            return theClass;
1064        }
1065
1066        if (isParentFirst(classname)) {
1067            try {
1068                theClass = findBaseClass(classname);
1069                log("Class " + classname + " loaded from parent loader "
1070                    + "(parentFirst)", Project.MSG_DEBUG);
1071            } catch (ClassNotFoundException JavaDoc cnfe) {
1072                theClass = findClass(classname);
1073                log("Class " + classname + " loaded from ant loader "
1074                    + "(parentFirst)", Project.MSG_DEBUG);
1075            }
1076        } else {
1077            try {
1078                theClass = findClass(classname);
1079                log("Class " + classname + " loaded from ant loader",
1080                    Project.MSG_DEBUG);
1081            } catch (ClassNotFoundException JavaDoc cnfe) {
1082                if (ignoreBase) {
1083                    throw cnfe;
1084                }
1085                theClass = findBaseClass(classname);
1086                log("Class " + classname + " loaded from parent loader",
1087                    Project.MSG_DEBUG);
1088            }
1089        }
1090
1091        if (resolve) {
1092            resolveClass(theClass);
1093        }
1094
1095        return theClass;
1096    }
1097
1098    /**
1099     * Converts the class dot notation to a filesystem equivalent for
1100     * searching purposes.
1101     *
1102     * @param classname The class name in dot format (eg java.lang.Integer).
1103     * Must not be <code>null</code>.
1104     *
1105     * @return the classname in filesystem format (eg java/lang/Integer.class)
1106     */

1107    private String JavaDoc getClassFilename(String JavaDoc classname) {
1108        return classname.replace('.', '/') + ".class";
1109    }
1110
1111    /**
1112     * Define a class given its bytes
1113     *
1114     * @param container the container from which the class data has been read
1115     * may be a directory or a jar/zip file.
1116     *
1117     * @param classData the bytecode data for the class
1118     * @param classname the name of the class
1119     *
1120     * @return the Class instance created from the given data
1121     *
1122     * @throws IOException if the class data cannot be read.
1123     */

1124    protected Class JavaDoc defineClassFromData(File JavaDoc container, byte[] classData,
1125                                        String JavaDoc classname) throws IOException JavaDoc {
1126        definePackage(container, classname);
1127        // XXX should instead make a new ProtectionDomain with a CodeSource
1128
// corresponding to container.toURI().toURL() and the same
1129
// PermissionCollection as Project.class.protectionDomain had
1130
return defineClass(classname, classData, 0, classData.length,
1131                           Project.class.getProtectionDomain());
1132    }
1133
1134    /**
1135     * Define the package information associated with a class.
1136     *
1137     * @param container the file containing the class definition.
1138     * @param className the class name of for which the package information
1139     * is to be determined.
1140     *
1141     * @exception IOException if the package information cannot be read from the
1142     * container.
1143     */

1144    protected void definePackage(File JavaDoc container, String JavaDoc className)
1145        throws IOException JavaDoc {
1146        int classIndex = className.lastIndexOf('.');
1147        if (classIndex == -1) {
1148            return;
1149        }
1150
1151        String JavaDoc packageName = className.substring(0, classIndex);
1152        if (getPackage(packageName) != null) {
1153            // already defined
1154
return;
1155        }
1156
1157        // define the package now
1158
Manifest JavaDoc manifest = getJarManifest(container);
1159
1160        if (manifest == null) {
1161            definePackage(packageName, null, null, null, null, null,
1162                          null, null);
1163        } else {
1164            definePackage(container, packageName, manifest);
1165        }
1166    }
1167
1168    /**
1169     * Get the manifest from the given jar, if it is indeed a jar and it has a
1170     * manifest
1171     *
1172     * @param container the File from which a manifest is required.
1173     *
1174     * @return the jar's manifest or null is the container is not a jar or it
1175     * has no manifest.
1176     *
1177     * @exception IOException if the manifest cannot be read.
1178     */

1179    private Manifest JavaDoc getJarManifest(File JavaDoc container) throws IOException JavaDoc {
1180        if (container.isDirectory()) {
1181            return null;
1182        }
1183        JarFile JavaDoc jarFile = null;
1184        try {
1185            jarFile = new JarFile JavaDoc(container);
1186            return jarFile.getManifest();
1187        } finally {
1188            if (jarFile != null) {
1189                jarFile.close();
1190            }
1191        }
1192    }
1193
1194    /**
1195     * Define the package information when the class comes from a
1196     * jar with a manifest
1197     *
1198     * @param container the jar file containing the manifest
1199     * @param packageName the name of the package being defined.
1200     * @param manifest the jar's manifest
1201     */

1202    protected void definePackage(File JavaDoc container, String JavaDoc packageName,
1203                                 Manifest JavaDoc manifest) {
1204        String JavaDoc sectionName = packageName.replace('.', '/') + "/";
1205
1206        String JavaDoc specificationTitle = null;
1207        String JavaDoc specificationVendor = null;
1208        String JavaDoc specificationVersion = null;
1209        String JavaDoc implementationTitle = null;
1210        String JavaDoc implementationVendor = null;
1211        String JavaDoc implementationVersion = null;
1212        String JavaDoc sealedString = null;
1213        URL JavaDoc sealBase = null;
1214
1215        Attributes JavaDoc sectionAttributes = manifest.getAttributes(sectionName);
1216        if (sectionAttributes != null) {
1217            specificationTitle
1218                = sectionAttributes.getValue(Name.SPECIFICATION_TITLE);
1219            specificationVendor
1220                = sectionAttributes.getValue(Name.SPECIFICATION_VENDOR);
1221            specificationVersion
1222                = sectionAttributes.getValue(Name.SPECIFICATION_VERSION);
1223            implementationTitle
1224                = sectionAttributes.getValue(Name.IMPLEMENTATION_TITLE);
1225            implementationVendor
1226                = sectionAttributes.getValue(Name.IMPLEMENTATION_VENDOR);
1227            implementationVersion
1228                = sectionAttributes.getValue(Name.IMPLEMENTATION_VERSION);
1229            sealedString
1230                = sectionAttributes.getValue(Name.SEALED);
1231        }
1232
1233        Attributes JavaDoc mainAttributes = manifest.getMainAttributes();
1234        if (mainAttributes != null) {
1235            if (specificationTitle == null) {
1236                specificationTitle
1237                    = mainAttributes.getValue(Name.SPECIFICATION_TITLE);
1238            }
1239            if (specificationVendor == null) {
1240                specificationVendor
1241                    = mainAttributes.getValue(Name.SPECIFICATION_VENDOR);
1242            }
1243            if (specificationVersion == null) {
1244                specificationVersion
1245                    = mainAttributes.getValue(Name.SPECIFICATION_VERSION);
1246            }
1247            if (implementationTitle == null) {
1248                implementationTitle
1249                    = mainAttributes.getValue(Name.IMPLEMENTATION_TITLE);
1250            }
1251            if (implementationVendor == null) {
1252                implementationVendor
1253                    = mainAttributes.getValue(Name.IMPLEMENTATION_VENDOR);
1254            }
1255            if (implementationVersion == null) {
1256                implementationVersion
1257                    = mainAttributes.getValue(Name.IMPLEMENTATION_VERSION);
1258            }
1259            if (sealedString == null) {
1260                sealedString
1261                    = mainAttributes.getValue(Name.SEALED);
1262            }
1263        }
1264
1265        if (sealedString != null && sealedString.equalsIgnoreCase("true")) {
1266            try {
1267                sealBase = new URL JavaDoc(FileUtils.getFileUtils().toURI(container.getAbsolutePath()));
1268            } catch (MalformedURLException JavaDoc e) {
1269                // ignore
1270
}
1271        }
1272
1273        definePackage(packageName, specificationTitle, specificationVersion,
1274                      specificationVendor, implementationTitle,
1275                      implementationVersion, implementationVendor, sealBase);
1276    }
1277
1278
1279    /**
1280     * Reads a class definition from a stream.
1281     *
1282     * @param stream The stream from which the class is to be read.
1283     * Must not be <code>null</code>.
1284     * @param classname The name of the class in the stream.
1285     * Must not be <code>null</code>.
1286     * @param container the file or directory containing the class.
1287     *
1288     * @return the Class object read from the stream.
1289     *
1290     * @exception IOException if there is a problem reading the class from the
1291     * stream.
1292     * @exception SecurityException if there is a security problem while
1293     * reading the class from the stream.
1294     */

1295    private Class JavaDoc getClassFromStream(InputStream JavaDoc stream, String JavaDoc classname,
1296                                     File JavaDoc container)
1297        throws IOException JavaDoc, SecurityException JavaDoc {
1298        ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
1299        int bytesRead = -1;
1300        byte[] buffer = new byte[BUFFER_SIZE];
1301
1302        while ((bytesRead = stream.read(buffer, 0, BUFFER_SIZE)) != -1) {
1303            baos.write(buffer, 0, bytesRead);
1304        }
1305
1306        byte[] classData = baos.toByteArray();
1307        return defineClassFromData(container, classData, classname);
1308    }
1309
1310    /**
1311     * Searches for and load a class on the classpath of this class loader.
1312     *
1313     * @param name The name of the class to be loaded. Must not be
1314     * <code>null</code>.
1315     *
1316     * @return the required Class object
1317     *
1318     * @exception ClassNotFoundException if the requested class does not exist
1319     * on this loader's classpath.
1320     */

1321    public Class JavaDoc findClass(String JavaDoc name) throws ClassNotFoundException JavaDoc {
1322        log("Finding class " + name, Project.MSG_DEBUG);
1323
1324        return findClassInComponents(name);
1325    }
1326
1327    /**
1328     * Indicate if the given file is in this loader's path
1329     *
1330     * @param component the file which is to be checked
1331     *
1332     * @return true if the file is in the class path
1333     */

1334    protected boolean isInPath(File JavaDoc component) {
1335        for (Enumeration JavaDoc e = pathComponents.elements(); e.hasMoreElements();) {
1336            File JavaDoc pathComponent = (File JavaDoc) e.nextElement();
1337            if (pathComponent.equals(component)) {
1338                return true;
1339            }
1340        }
1341        return false;
1342    }
1343
1344
1345    /**
1346     * Finds a class on the given classpath.
1347     *
1348     * @param name The name of the class to be loaded. Must not be
1349     * <code>null</code>.
1350     *
1351     * @return the required Class object
1352     *
1353     * @exception ClassNotFoundException if the requested class does not exist
1354     * on this loader's classpath.
1355     */

1356    private Class JavaDoc findClassInComponents(String JavaDoc name)
1357        throws ClassNotFoundException JavaDoc {
1358        // we need to search the components of the path to see if
1359
// we can find the class we want.
1360
InputStream JavaDoc stream = null;
1361        String JavaDoc classFilename = getClassFilename(name);
1362        try {
1363            Enumeration JavaDoc e = pathComponents.elements();
1364            while (e.hasMoreElements()) {
1365                File JavaDoc pathComponent = (File JavaDoc) e.nextElement();
1366                try {
1367                    stream = getResourceStream(pathComponent, classFilename);
1368                    if (stream != null) {
1369                        log("Loaded from " + pathComponent + " "
1370                            + classFilename, Project.MSG_DEBUG);
1371                        return getClassFromStream(stream, name, pathComponent);
1372                    }
1373                } catch (SecurityException JavaDoc se) {
1374                    throw se;
1375                } catch (IOException JavaDoc ioe) {
1376                    // ioe.printStackTrace();
1377
log("Exception reading component " + pathComponent
1378                        + " (reason: " + ioe.getMessage() + ")",
1379                        Project.MSG_VERBOSE);
1380                }
1381            }
1382
1383            throw new ClassNotFoundException JavaDoc(name);
1384        } finally {
1385            try {
1386                if (stream != null) {
1387                    stream.close();
1388                }
1389            } catch (IOException JavaDoc e) {
1390                //ignore
1391
}
1392        }
1393    }
1394
1395    /**
1396     * Finds a system class (which should be loaded from the same classloader
1397     * as the Ant core).
1398     *
1399     * For JDK 1.1 compatibility, this uses the findSystemClass method if
1400     * no parent classloader has been specified.
1401     *
1402     * @param name The name of the class to be loaded.
1403     * Must not be <code>null</code>.
1404     *
1405     * @return the required Class object
1406     *
1407     * @exception ClassNotFoundException if the requested class does not exist
1408     * on this loader's classpath.
1409     */

1410    private Class JavaDoc findBaseClass(String JavaDoc name) throws ClassNotFoundException JavaDoc {
1411        if (parent == null) {
1412            return findSystemClass(name);
1413        } else {
1414            return parent.loadClass(name);
1415        }
1416    }
1417
1418    /**
1419     * Cleans up any resources held by this classloader. Any open archive
1420     * files are closed.
1421     */

1422    public synchronized void cleanup() {
1423        for (Enumeration JavaDoc e = zipFiles.elements(); e.hasMoreElements();) {
1424            ZipFile JavaDoc zipFile = (ZipFile JavaDoc) e.nextElement();
1425            try {
1426                zipFile.close();
1427            } catch (IOException JavaDoc ioe) {
1428                // ignore
1429
}
1430        }
1431        zipFiles = new Hashtable JavaDoc();
1432        if (project != null) {
1433            project.removeBuildListener(this);
1434        }
1435        project = null;
1436    }
1437
1438    /**
1439     * Empty implementation to satisfy the BuildListener interface.
1440     *
1441     * @param event the buildStarted event
1442     */

1443    public void buildStarted(BuildEvent event) {
1444        // Not significant for the class loader.
1445
}
1446
1447    /**
1448     * Cleans up any resources held by this classloader at the end
1449     * of a build.
1450     *
1451     * @param event the buildFinished event
1452     */

1453    public void buildFinished(BuildEvent event) {
1454        cleanup();
1455    }
1456
1457    /**
1458     * Cleans up any resources held by this classloader at the end of
1459     * a subbuild if it has been created for the subbuild's project
1460     * instance.
1461     *
1462     * @param event the buildFinished event
1463     *
1464     * @since Ant 1.6.2
1465     */

1466    public void subBuildFinished(BuildEvent event) {
1467        if (event.getProject() == project) {
1468            cleanup();
1469        }
1470    }
1471
1472    /**
1473     * Empty implementation to satisfy the BuildListener interface.
1474     *
1475     * @param event the buildStarted event
1476     *
1477     * @since Ant 1.6.2
1478     */

1479    public void subBuildStarted(BuildEvent event) {
1480        // Not significant for the class loader.
1481
}
1482
1483    /**
1484     * Empty implementation to satisfy the BuildListener interface.
1485     *
1486     * @param event the targetStarted event
1487     */

1488    public void targetStarted(BuildEvent event) {
1489        // Not significant for the class loader.
1490
}
1491
1492    /**
1493     * Empty implementation to satisfy the BuildListener interface.
1494     *
1495     * @param event the targetFinished event
1496     */

1497    public void targetFinished(BuildEvent event) {
1498        // Not significant for the class loader.
1499
}
1500
1501    /**
1502     * Empty implementation to satisfy the BuildListener interface.
1503     *
1504     * @param event the taskStarted event
1505     */

1506    public void taskStarted(BuildEvent event) {
1507        // Not significant for the class loader.
1508
}
1509
1510    /**
1511     * Empty implementation to satisfy the BuildListener interface.
1512     *
1513     * @param event the taskFinished event
1514     */

1515    public void taskFinished(BuildEvent event) {
1516        // Not significant for the class loader.
1517
}
1518
1519    /**
1520     * Empty implementation to satisfy the BuildListener interface.
1521     *
1522     * @param event the messageLogged event
1523     */

1524    public void messageLogged(BuildEvent event) {
1525        // Not significant for the class loader.
1526
}
1527
1528    /**
1529     * add any libraries that come with different java versions
1530     * here
1531     */

1532    public void addJavaLibraries() {
1533        Vector JavaDoc packages = JavaEnvUtils.getJrePackages();
1534        Enumeration JavaDoc e = packages.elements();
1535        while (e.hasMoreElements()) {
1536            String JavaDoc packageName = (String JavaDoc) e.nextElement();
1537            addSystemPackageRoot(packageName);
1538        }
1539    }
1540
1541    /**
1542     * Returns a <code>String</code> representing this loader.
1543     * @return the path that this classloader has.
1544     */

1545    public String JavaDoc toString() {
1546        return "AntClassLoader[" + getClasspath() + "]";
1547    }
1548
1549}
1550
Popular Tags