--- src/main/org/apache/tools/ant/AntClassLoader.java (revision 446566) +++ src/main/org/apache/tools/ant/AntClassLoader.java (working copy) @@ -261,7 +261,7 @@ * elements are set up to start with. */ public AntClassLoader(Project project, Path classpath) { - setParent(null); + setParent(project.getCoreLoader()); setProject(project); setClassPath(classpath); } @@ -307,7 +307,7 @@ */ public AntClassLoader(Project project, Path classpath, boolean parentFirst) { - this(null, project, classpath, parentFirst); + this(project.getCoreLoader(), project, classpath, parentFirst); } /** --- src/main/org/apache/tools/ant/ComponentHelper.java (revision 446566) +++ src/main/org/apache/tools/ant/ComponentHelper.java (working copy) @@ -264,6 +264,22 @@ } /** + * Reset the classloaders for those types that have + * not yet been instaniated. + */ + protected void resetCoreLoader( + ClassLoader oldLoader, ClassLoader newLoader) { + for (Iterator i = antTypeTable.values().iterator(); i.hasNext();) { + AntTypeDefinition def = (AntTypeDefinition) i.next(); + Class clazz = def.getClazz(); + ClassLoader loader = def.getClassLoader(); + if (clazz == null && (loader == oldLoader)) { + def.setClassLoader(newLoader); + } + } + } + + /** * This method is initialization code implementing the original ant component * loading from /org/apache/tools/ant/taskdefs/default.properties * and /org/apache/tools/ant/types/default.properties. --- src/main/org/apache/tools/ant/Project.java (revision 446566) +++ src/main/org/apache/tools/ant/Project.java (working copy) @@ -163,10 +163,10 @@ private Vector listeners = new Vector(); /** - * The Ant core classloader--may be null if using - * parent classloader. + * The Ant core classloader. + * This is used for loading in tasks and types. */ - private ClassLoader coreLoader = null; + private ClassLoader coreLoader = Project.class.getClassLoader(); /** Records the latest task to be executed on a thread. */ private Map/**/ threadTasks = Collections.synchronizedMap(new WeakHashMap()); @@ -316,7 +316,7 @@ */ public AntClassLoader createClassLoader(Path path) { return new AntClassLoader( - getClass().getClassLoader(), this, path); + getCoreLoader(), this, path); } /** @@ -337,11 +337,27 @@ * Set the core classloader for the project. If a null * classloader is specified, the parent classloader should be used. * + * The coreLoader *must* be able to loader *this* Project class. * @param coreLoader The classloader to use for the project. * May be null. */ public void setCoreLoader(ClassLoader coreLoader) { + if (coreLoader == null) { + coreLoader = getClass().getClassLoader(); + } + try { + Class cl = coreLoader.loadClass(getClass().getName()); + if (cl != getClass()) { + throw new BuildException( + "Invalid coreLoader - it " + + "returns an incorrect Project.class"); + } + } catch (Exception ex) { + throw new BuildException("unable to use coreloader", ex); + } + ComponentHelper.getComponentHelper(this) + .resetCoreLoader(this.coreLoader, coreLoader); this.coreLoader = coreLoader; } --- src/main/org/apache/tools/ant/taskdefs/Classloader.java (revision 446566) +++ src/main/org/apache/tools/ant/taskdefs/Classloader.java (working copy) @@ -167,7 +167,6 @@ } AntClassLoader acl = (AntClassLoader) obj; - if (acl == null) { // Construct a new class loader Object parent = null; @@ -197,8 +196,13 @@ if (name == null) { // This allows the core loader to load optional tasks - // without delegating - acl.addLoaderPackageRoot("org.apache.tools.ant.taskdefs.optional"); + // and types without delegating + acl.addLoaderPackageRoot( + "org.apache.tools.ant.taskdefs.optional"); + acl.addLoaderPackageRoot( + "org.apache.tools.ant.types.optional"); + acl.addLoaderPackageRoot( + "org.apache.tools.ant.util.optional"); getProject().setCoreLoader(acl); } } @@ -214,10 +218,9 @@ } } - // XXX add exceptions - } catch (Exception ex) { - ex.printStackTrace(); + throw new BuildException(ex); } } } --- src/main/org/apache/tools/ant/AntTypeDefinition.java (revision 446566) +++ src/main/org/apache/tools/ant/AntTypeDefinition.java (working copy) @@ -56,7 +56,14 @@ } /** + * Return the current value of clazz. + */ + protected Class getClazz() { + return clazz; + } + + /** * Set the class of the definition. * As a side-effect may set the classloader and classname. * @param clazz the class of this definition.