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-ffa450edef68master
@@ -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 | ||||
=================================== | =================================== | ||||
@@ -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}"/> | ||||
@@ -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); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
@@ -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(); | |||||
} | |||||
} | |||||
} | |||||
} | } |
@@ -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); | |||||
} | |||||
} | |||||
} | |||||
} | } | ||||