Browse Source

Impossible to use implicit classpath for <taskdef> when Ant core loader != Java application loader and Path.systemClassPath taken from ${java.class.path}

PR: 30161
Submitted by: Jesse Glick (jglick at netbeans dot org)


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@276721 13f79535-47bb-0310-9956-ffa450edef68
master
Antoine Levy-Lambert 21 years ago
parent
commit
8fdf272627
5 changed files with 125 additions and 6 deletions
  1. +4
    -0
      WHATSNEW
  2. +2
    -2
      build.xml
  3. +19
    -2
      src/main/org/apache/tools/ant/AntClassLoader.java
  4. +35
    -0
      src/main/org/apache/tools/ant/util/CollectionUtils.java
  5. +65
    -2
      src/testcases/org/apache/tools/ant/AntClassLoaderTest.java

+ 4
- 0
WHATSNEW View File

@@ -48,6 +48,10 @@ Fixed bugs:
* AbstractCvsTask prematurely closed its outputStream and errorStream. * AbstractCvsTask prematurely closed its outputStream and errorStream.
Bugzilla 30097. Bugzilla 30097.


* Impossible to use implicit classpath for <taskdef>
when Ant core loader != Java application loader and Path.systemClassPath taken from ${java.class.path}
Bugzilla 30161.

Changes from Ant 1.6.1 to Ant 1.6.2 Changes from Ant 1.6.1 to Ant 1.6.2
=================================== ===================================




+ 2
- 2
build.xml View File

@@ -1456,7 +1456,7 @@
<classpath refid="tests-classpath"/> <classpath refid="tests-classpath"/>


<sysproperty key="ant.home" value="${ant.home}"/> <sysproperty key="ant.home" value="${ant.home}"/>
<sysproperty key="build.tests" value="${build.tests}"/>
<sysproperty key="build.tests" file="${build.tests}"/>
<sysproperty key="build.tests.value" value="${build.tests.value}"/> <sysproperty key="build.tests.value" value="${build.tests.value}"/>
<sysproperty key="tests-classpath.value" <sysproperty key="tests-classpath.value"
value="${tests-classpath.value}"/> value="${tests-classpath.value}"/>
@@ -1606,7 +1606,7 @@
filtertrace="${junit.filtertrace}"> filtertrace="${junit.filtertrace}">
<!-- <jvmarg value="-classic"/> --> <!-- <jvmarg value="-classic"/> -->
<sysproperty key="ant.home" value="${ant.home}"/> <sysproperty key="ant.home" value="${ant.home}"/>
<sysproperty key="build.tests" value="${build.tests}"/>
<sysproperty key="build.tests" file="${build.tests}"/>
<sysproperty key="build.tests.value" value="${build.tests.value}"/> <sysproperty key="build.tests.value" value="${build.tests.value}"/>
<sysproperty key="tests-classpath.value" <sysproperty key="tests-classpath.value"
value="${tests-classpath.value}"/> value="${tests-classpath.value}"/>


+ 19
- 2
src/main/org/apache/tools/ant/AntClassLoader.java View File

@@ -32,6 +32,7 @@ import java.util.Vector;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
import org.apache.tools.ant.types.Path; import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.util.CollectionUtils;
import org.apache.tools.ant.util.FileUtils; import org.apache.tools.ant.util.FileUtils;
import org.apache.tools.ant.util.JavaEnvUtils; import org.apache.tools.ant.util.JavaEnvUtils;
import org.apache.tools.ant.util.LoaderUtils; import org.apache.tools.ant.util.LoaderUtils;
@@ -864,8 +865,24 @@ public class AntClassLoader extends ClassLoader implements SubBuildListener {
* @return an enumeration of URLs for the resources * @return an enumeration of URLs for the resources
* @exception IOException if I/O errors occurs (can't happen) * @exception IOException if I/O errors occurs (can't happen)
*/ */
protected Enumeration findResources(String name) throws IOException {
return new ResourceEnumeration(name);
protected Enumeration/*<URL>*/ findResources(String name) throws IOException {
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 {
// Inverted.
return CollectionUtils.append(mine, base);
}
} }


/** /**


+ 35
- 0
src/main/org/apache/tools/ant/util/CollectionUtils.java View File

@@ -113,4 +113,39 @@ public class CollectionUtils {
} }
} }


/**
* Append one enumeration to another.
* Elements are evaluated lazily.
* @param e1 the first enumeration
* @param e2 the subsequent enumeration
* @return an enumeration representing e1 followed by e2
* @since Ant 1.6.3
*/
public static Enumeration append(Enumeration e1, Enumeration e2) {
return new CompoundEnumeration(e1, e2);
}

private static final class CompoundEnumeration implements Enumeration {

private final Enumeration e1, e2;

public CompoundEnumeration(Enumeration e1, Enumeration e2) {
this.e1 = e1;
this.e2 = e2;
}

public boolean hasMoreElements() {
return e1.hasMoreElements() || e2.hasMoreElements();
}

public Object nextElement() throws NoSuchElementException {
if (e1.hasMoreElements()) {
return e1.nextElement();
} else {
return e2.nextElement();
}
}

}

} }

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

@@ -16,8 +16,20 @@
*/ */


package org.apache.tools.ant; package org.apache.tools.ant;
import org.apache.tools.ant.types.Path;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.util.FileUtils;


/** /**
* Test case for ant class loader * Test case for ant class loader
@@ -70,5 +82,56 @@ public class AntClassLoaderTest extends TestCase {
fail("loader should not fail even if project finished"); fail("loader should not fail even if project finished");
} }
} }
/** Sample resource present in build/testcases/ */
private static final String TEST_RESOURCE = "org/apache/tools/ant/IncludeTest.class";
public void testFindResources() throws Exception {
//System.err.println("loading from: " + AntClassLoader.class.getProtectionDomain().getCodeSource().getLocation());
// See bug #30161.
// This path should contain the class files for these testcases:
String buildTestcases = System.getProperty("build.tests");
assertNotNull("defined ${build.tests}", buildTestcases);
assertTrue("have a dir " + buildTestcases, new File(buildTestcases).isDirectory());
Path path = new Path(p, buildTestcases);
// A special parent loader which is not the system class loader:
ClassLoader parent = new ParentLoader();
// An AntClassLoader which is supposed to delegate to the parent and then to the disk path:
ClassLoader acl = new AntClassLoader(parent, p, path, true);
// The intended result URLs:
URL urlFromPath = new URL(FileUtils.newFileUtils().toURI(buildTestcases) + TEST_RESOURCE);
URL urlFromParent = new URL("http://ant.apache.org/" + TEST_RESOURCE);
assertEquals("correct resources (regular delegation order)",
Arrays.asList(new URL[] {urlFromParent, urlFromPath}),
enum2List(acl.getResources(TEST_RESOURCE)));
acl = new AntClassLoader(parent, p, path, false);
assertEquals("correct resources (reverse delegation order)",
Arrays.asList(new URL[] {urlFromPath, urlFromParent}),
enum2List(acl.getResources(TEST_RESOURCE)));
}
private static List enum2List(Enumeration e) {
// JDK 1.4: return Collections.list(e);
List l = new ArrayList();
while (e.hasMoreElements()) {
l.add(e.nextElement());
}
return l;
}
/** Special loader that just knows how to find TEST_RESOURCE. */
private static final class ParentLoader extends ClassLoader {
public ParentLoader() {}
protected Enumeration findResources(String name) throws IOException {
if (name.equals(TEST_RESOURCE)) {
return Collections.enumeration(Collections.singleton(new URL("http://ant.apache.org/" + name)));
} else {
return Collections.enumeration(Collections.EMPTY_SET);
}
}
}
} }


Loading…
Cancel
Save