Browse Source

Set the parent of the antClassLoader correctly: bugzilla 35436

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@439801 13f79535-47bb-0310-9956-ffa450edef68
master
Peter Reilly 19 years ago
parent
commit
56e61f039f
6 changed files with 85 additions and 14 deletions
  1. +1
    -0
      WHATSNEW
  2. +59
    -1
      src/main/org/apache/tools/ant/AntClassLoader.java
  3. +18
    -5
      src/main/org/apache/tools/ant/Project.java
  4. +4
    -4
      src/main/org/apache/tools/ant/types/selectors/modifiedselector/ModifiedSelector.java
  5. +2
    -3
      src/main/org/apache/tools/ant/util/ScriptRunner.java
  6. +1
    -1
      src/testcases/org/apache/tools/ant/AntClassLoaderTest.java

+ 1
- 0
WHATSNEW View File

@@ -5,6 +5,7 @@ Changes that could break older environments:
-------------------------------------------

* <script> and <scriptdef> now set the current thread context.
* AntClassLoader now sets the parent classloader. Bugzilla report 35436.

Fixed bugs:
-----------


+ 59
- 1
src/main/org/apache/tools/ant/AntClassLoader.java View File

@@ -26,6 +26,7 @@ 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;
@@ -59,6 +60,19 @@ import org.apache.tools.ant.launch.Locator;
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
@@ -216,8 +230,31 @@ public class AntClassLoader extends ClassLoader implements SubBuildListener {
*/
private boolean isContextLoaderSaved = false;

/**
* 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
* belong.
* @param classpath The classpath to use to load classes.
*/
public AntClassLoader(
ClassLoader parent, Project project, Path classpath) {
super(parent == null ? AntClassLoader.class.getClassLoader() : parent);
this.parent = getParent();
setClassPath(classpath);
setProject(project);
}

/**
* Create an Ant Class Loader
* @deprecated by AntClassLoader(parent, project, classpath) since Ant 1.7.
*/
public AntClassLoader() {
setParent(null);
@@ -233,6 +270,7 @@ 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);
@@ -255,6 +293,7 @@ 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) {
@@ -278,6 +317,7 @@ 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) {
@@ -296,6 +336,7 @@ 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);
@@ -307,6 +348,7 @@ 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;
@@ -343,13 +385,29 @@ 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) {
private void setParent(ClassLoader parent) {
if (parent == null) {
this.parent = AntClassLoader.class.getClassLoader();
} 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
}
}

/**


+ 18
- 5
src/main/org/apache/tools/ant/Project.java View File

@@ -300,7 +300,8 @@ public class Project implements ResourceFactory {
}

private void setAntLib() {
File antlib = org.apache.tools.ant.launch.Locator.getClassSource(Project.class);
File antlib = org.apache.tools.ant.launch.Locator.getClassSource(
Project.class);
if (antlib != null) {
setPropertyInternal(MagicNames.ANT_LIB, antlib.getAbsolutePath());
}
@@ -314,10 +315,22 @@ public class Project implements ResourceFactory {
* @return an appropriate classloader.
*/
public AntClassLoader createClassLoader(Path path) {
AntClassLoader loader = new AntClassLoader();
loader.setProject(this);
loader.setClassPath(path);
return loader;
return new AntClassLoader(
getClass().getClassLoader(), this, path);
}

/**
* Factory method to create a class loader for loading classes from
* a given path.
*
* @param parent the parent classloader for the new loader.
* @param path the path from which classes are to be loaded.
*
* @return an appropriate classloader.
*/
public AntClassLoader createClassLoader(
ClassLoader parent, Path path) {
return new AntClassLoader(parent, this, path);
}

/**


+ 4
- 4
src/main/org/apache/tools/ant/types/selectors/modifiedselector/ModifiedSelector.java View File

@@ -736,10 +736,10 @@ public class ModifiedSelector extends BaseExtendSelector
public ClassLoader getClassLoader() {
if (myClassLoader == null) {
myClassLoader = (classpath == null)
// the usual classloader
? getClass().getClassLoader()
// additional use the provided classpath
: new org.apache.tools.ant.AntClassLoader(getProject(), classpath);
// the usual classloader
? getClass().getClassLoader()
// additional use the provided classpath
: getProject().createClassLoader(classpath);
}
return myClassLoader;
}


+ 2
- 3
src/main/org/apache/tools/ant/util/ScriptRunner.java View File

@@ -124,9 +124,8 @@ public class ScriptRunner {
Thread.currentThread().getContextClassLoader();
ClassLoader scriptLoader = getClass().getClassLoader();
if (classpath != null && project != null) {
AntClassLoader loader = project.createClassLoader(classpath);
loader.setParent(scriptLoader);
scriptLoader = loader;
scriptLoader = project.createClassLoader(
scriptLoader, classpath);
}
try {
Thread.currentThread().setContextClassLoader(scriptLoader);


+ 1
- 1
src/testcases/org/apache/tools/ant/AntClassLoaderTest.java View File

@@ -66,7 +66,7 @@ public class AntClassLoaderTest extends BuildFileTest {
}
public void testCleanup() throws BuildException {
Path path = new Path(p, ".");
AntClassLoader loader = new AntClassLoader(p, path);
AntClassLoader loader = p.createClassLoader(path);
try {
// we don't expect to find this
loader.findClass("fubar");


Loading…
Cancel
Save