Problem Overview: Each ClassLoader itself can only load classes in specific locations and directories separately, but ClassLoader is designed to be a delegate pattern that allows one classloader to delegate its parent class loader to load classes. So that the application can use the classloader of a certain child to the loading of classes in multiple locations and directories. This is like "son" besides can spend his own money, he can also spend "father" money, "father" can also spend "father's father" money, so, finally through the "son" spent money, including his predecessors of the money. Class loaders are delegated to the Bootstrap class loader at the first level, and when Bootstrap cannot load the class that is currently being loaded, then the first level is then rolled back to the Descendants class loader for real loading. When you fall back to the original class loader, if it cannot complete the load of the class itself, you should report the classnotfoundexception exception.
 
The problem now is that I've written a class loader to load classes in a particular directory, and when I test this class loader with Java.exe, the test results are completely normal and you see the delegate effect. And I use the Ant tool to invoke the test program, the result is somewhat problematic, I write the class loader does not seem to entrust its parent class loader to load the class, and always load itself. Because I am shallow, and really do not have the energy to study the ant tool source code, can not understand its class loading internal details, now specifically for this problem, to the real Java experts to consult. In order to facilitate the experts to quickly understand my problem, but also easy to learn some of the hands, I wrote a detailed experiment steps, for the Java novice, suggest not to participate in the discussion, lest I delay your valuable time.
 
1. SOURCE program: Mainclass.java
 
package cn.itcast;
 public class MainClass
 {
   public static void main(String [] args)
   {
    ClassLoader loader = MainClass.class.getClassLoader();
    //打印出当前的类装载器,及该类装载器的各级父类装载器
    while(loader != null)
    {
     System.out.println(loader.getClass().getName());
     loader = loader.getParent();
    }
    //加载AuxiliaryClass类
    System.out.println(AuxiliaryClass.class.getName());
   }
 }
 
SOURCE program: Auxiliaryclass.java
 
package cn.itcast;
 public class AuxiliaryClass
 {}
 
2. Directory structure of source file and build result file
 
f:\project
 |__src
 | |__cn
 | |__itcast
 | |__MainClass.java
 | |__AuxiliaryClass.java
 |__build.xml
 |__classes
 |__cn
 |__itcast
 |__MainClass.class
 |__AuxiliaryClass.class
 
3.build.xml File Contents
 
<project name="antloader" default="run">
 <property name="classes.dir" value="classes" />
 <property name="src.dir" value="src" />
 <target name="init">
 <mkdir dir="${classes.dir}" />
 </target>
 <target name="compile" depends="init">
 <javac destdir="${classes.dir}" >
 <src path="${src.dir}" />
 </javac>
 </target>
 <target name="run" depends="compile">
 <java classname="cn.itcast.MyClassLoader">
 <classpath>
 <pathelement location="${classes.dir}"/>
 </classpath>
 </java>
 </target>
 </project>