|
|
@@ -26,7 +26,6 @@ import java.io.InputStream; |
|
|
|
import java.io.InputStreamReader; |
|
|
|
import java.io.Reader; |
|
|
|
import java.lang.reflect.Constructor; |
|
|
|
import java.lang.reflect.Field; |
|
|
|
import java.net.MalformedURLException; |
|
|
|
import java.net.URL; |
|
|
|
import java.util.Collections; |
|
|
@@ -57,23 +56,19 @@ import org.apache.tools.ant.launch.Locator; |
|
|
|
* using the forceLoadClass method. Any subsequent classes loaded by that |
|
|
|
* class will then use this loader rather than the system class loader. |
|
|
|
* |
|
|
|
* <p> |
|
|
|
* Note that this classloader has a feature to allow loading |
|
|
|
* in reverse order and for "isolation". |
|
|
|
* Due to the fact that a number of |
|
|
|
* methods in java.lang.ClassLoader are final (at least |
|
|
|
* in java 1.4 getResources) this means that the |
|
|
|
* class has to fake the given parent. |
|
|
|
* </p> |
|
|
|
* |
|
|
|
*/ |
|
|
|
public class AntClassLoader extends ClassLoader implements SubBuildListener { |
|
|
|
|
|
|
|
private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); |
|
|
|
/** |
|
|
|
* Work around for deprecated constructors that did |
|
|
|
* not set the parent classloader. |
|
|
|
*/ |
|
|
|
private static Field parentField; |
|
|
|
static { |
|
|
|
try { |
|
|
|
parentField = ClassLoader.class.getDeclaredField("parent"); |
|
|
|
parentField.setAccessible(true); |
|
|
|
} catch (Throwable t) { |
|
|
|
// Ignore |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* An enumeration of all resources of a given name found within the |
|
|
@@ -234,11 +229,6 @@ public class AntClassLoader extends ClassLoader implements SubBuildListener { |
|
|
|
/** |
|
|
|
* Create an Ant ClassLoader for a given project, with |
|
|
|
* a parent classloader and an initial classpath. |
|
|
|
* <p> |
|
|
|
* This constructor has been added in ant 1.7, it |
|
|
|
* sets the parent classloader correctly. All the |
|
|
|
* other constructors are deprecated. |
|
|
|
* </p> |
|
|
|
* @since Ant 1.7. |
|
|
|
* @param parent the parent for this classloader. |
|
|
|
* @param project The project to which this classloader is to |
|
|
@@ -247,15 +237,13 @@ public class AntClassLoader extends ClassLoader implements SubBuildListener { |
|
|
|
*/ |
|
|
|
public AntClassLoader( |
|
|
|
ClassLoader parent, Project project, Path classpath) { |
|
|
|
super(parent == null ? AntClassLoader.class.getClassLoader() : parent); |
|
|
|
this.parent = getParent(); |
|
|
|
setParent(parent); |
|
|
|
setClassPath(classpath); |
|
|
|
setProject(project); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Create an Ant Class Loader |
|
|
|
* @deprecated by AntClassLoader(parent, project, classpath) since Ant 1.7. |
|
|
|
*/ |
|
|
|
public AntClassLoader() { |
|
|
|
setParent(null); |
|
|
@@ -271,7 +259,6 @@ public class AntClassLoader extends ClassLoader implements SubBuildListener { |
|
|
|
* determined by the value of ${build.sysclasspath}. |
|
|
|
* May be <code>null</code>, in which case no path |
|
|
|
* elements are set up to start with. |
|
|
|
* @deprecated by AntClassLoader(parent, project, classpath) since Ant 1.7. |
|
|
|
*/ |
|
|
|
public AntClassLoader(Project project, Path classpath) { |
|
|
|
setParent(null); |
|
|
@@ -294,7 +281,6 @@ public class AntClassLoader extends ClassLoader implements SubBuildListener { |
|
|
|
* @param parentFirst If <code>true</code>, indicates that the parent |
|
|
|
* classloader should be consulted before trying to |
|
|
|
* load the a class through this loader. |
|
|
|
* @deprecated by AntClassLoader(parent, project, classpath) since Ant 1.7. |
|
|
|
*/ |
|
|
|
public AntClassLoader(ClassLoader parent, Project project, Path classpath, |
|
|
|
boolean parentFirst) { |
|
|
@@ -318,7 +304,6 @@ public class AntClassLoader extends ClassLoader implements SubBuildListener { |
|
|
|
* @param parentFirst If <code>true</code>, indicates that the parent |
|
|
|
* classloader should be consulted before trying to |
|
|
|
* load the a class through this loader. |
|
|
|
* @deprecated by AntClassLoader(parent, project, classpath) since Ant 1.7. |
|
|
|
*/ |
|
|
|
public AntClassLoader(Project project, Path classpath, |
|
|
|
boolean parentFirst) { |
|
|
@@ -337,7 +322,6 @@ public class AntClassLoader extends ClassLoader implements SubBuildListener { |
|
|
|
* @param parentFirst If <code>true</code>, indicates that the parent |
|
|
|
* classloader should be consulted before trying to |
|
|
|
* load the a class through this loader. |
|
|
|
* @deprecated by AntClassLoader(parent, project, classpath) since Ant 1.7. |
|
|
|
*/ |
|
|
|
public AntClassLoader(ClassLoader parent, boolean parentFirst) { |
|
|
|
setParent(parent); |
|
|
@@ -349,7 +333,6 @@ public class AntClassLoader extends ClassLoader implements SubBuildListener { |
|
|
|
* Set the project associated with this class loader |
|
|
|
* |
|
|
|
* @param project the project instance |
|
|
|
* @deprecated by AntClassLoader(parent, project, classpath) since Ant 1.7. |
|
|
|
*/ |
|
|
|
public void setProject(Project project) { |
|
|
|
this.project = project; |
|
|
@@ -386,7 +369,6 @@ public class AntClassLoader extends ClassLoader implements SubBuildListener { |
|
|
|
* this class loader will delegate to load classes |
|
|
|
* |
|
|
|
* @param parent the parent class loader. |
|
|
|
* @deprecated by AntClassLoader(parent, project, classpath) since Ant 1.7. |
|
|
|
*/ |
|
|
|
public void setParent(ClassLoader parent) { |
|
|
|
if (parent == null) { |
|
|
@@ -394,23 +376,6 @@ public class AntClassLoader extends ClassLoader implements SubBuildListener { |
|
|
|
} else { |
|
|
|
this.parent = parent; |
|
|
|
} |
|
|
|
// ClassLoader.parent is private and there is |
|
|
|
// no accessor to set it, there is an accessor |
|
|
|
// to get it, but it is final. |
|
|
|
// This method setParent sets the parent of |
|
|
|
// this classloader, and that is the way that the |
|
|
|
// class behaves - so use a bit of reflection |
|
|
|
// to set the field. |
|
|
|
|
|
|
|
if (parentField == null) { |
|
|
|
return; // Unable to get access to the parent field |
|
|
|
} |
|
|
|
try { |
|
|
|
parentField.set(this, parent); |
|
|
|
} catch (Throwable t) { |
|
|
|
// Ignore - unable to set the parent |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@@ -973,7 +938,26 @@ public class AntClassLoader extends ClassLoader implements SubBuildListener { |
|
|
|
* @exception IOException if I/O errors occurs (can't happen) |
|
|
|
*/ |
|
|
|
protected Enumeration/*<URL>*/ findResources(String name) throws IOException { |
|
|
|
return new ResourceEnumeration(name); |
|
|
|
Enumeration/*<URL>*/ mine = new ResourceEnumeration(name); |
|
|
|
Enumeration/*<URL>*/ base; |
|
|
|
if (parent != null && parent != getParent()) { |
|
|
|
// Delegate to the parent: |
|
|
|
base = parent.getResources(name); |
|
|
|
// Note: could cause overlaps in case ClassLoader.this.parent has matches. |
|
|
|
} else { |
|
|
|
// ClassLoader.this.parent is already delegated to from |
|
|
|
// ClassLoader.getResources, no need: |
|
|
|
base = new CollectionUtils.EmptyEnumeration(); |
|
|
|
} |
|
|
|
if (isParentFirst(name)) { |
|
|
|
// Normal case. |
|
|
|
return CollectionUtils.append(base, mine); |
|
|
|
} else if (isolated) { |
|
|
|
return mine; |
|
|
|
} else { |
|
|
|
// Inverted. |
|
|
|
return CollectionUtils.append(mine, base); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@@ -1538,33 +1522,6 @@ public class AntClassLoader extends ClassLoader implements SubBuildListener { |
|
|
|
return "AntClassLoader[" + getClasspath() + "]"; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Override ClassLoader.getResources() to handle the reverse case |
|
|
|
* and the isolate case. |
|
|
|
* @param name The resource name to seach for. |
|
|
|
* @return an enumeration of URLs for the resources |
|
|
|
* @exception IOException if I/O errors occurs. |
|
|
|
*/ |
|
|
|
public Enumeration getResources(String name) throws IOException { |
|
|
|
Enumeration parentEnum; |
|
|
|
if (parent != null) { |
|
|
|
parentEnum = parent.getResources(name); |
|
|
|
} else { |
|
|
|
// ClassLoader.getBootstrapResources(name) is private - so fake it |
|
|
|
parentEnum = new ClassLoader(){}.getResources(name); |
|
|
|
} |
|
|
|
Enumeration mine = findResources(name); |
|
|
|
boolean parentEnumFirst = isParentFirst(name); |
|
|
|
|
|
|
|
if (isolated && !parentEnumFirst) { |
|
|
|
return mine; |
|
|
|
} else if (parentEnumFirst) { |
|
|
|
return CollectionUtils.append(parentEnum, mine); |
|
|
|
} else { |
|
|
|
return CollectionUtils.append(mine, parentEnum); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Accessor for derived classloaders to access the path components. |
|
|
|
* @return the pathcomponents. |
|
|
|