DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT <http://nagoya.apache.org/bugzilla/show_bug.cgi?id=6606>. ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND INSERTED IN THE BUG DATABASE.
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=6606 META-BUG problems with delegating classloaders ------- Additional Comments From [EMAIL PROTECTED] 2002-02-21 11:19 ------- OK, first of all let's state that Ant adds all .jar files from ANT_HOME/lib to CLASSPATH, therefore when I say "in CLASSPATH" in the rest, it means "either in your CLASSPATH environment or ANT_HOME/lib". This bug collects a common type of problem: A task needs an external library and it has a nested classpath element so that you can point it to this external library, but that doesn't work unless you put the external library into the CLASSPATH. The root of the problem is that the class that needs the external library is on the CLASSPATH. When you specify a nested <classpath> in Ant, Ant creates a new class loader that uses the path you have specified. It then tries to load additional classes from this classloader. In most cases - for example the two cases above - Ant doesn't load the external library directly, it is the loaded class that does so. In the case of <junit> it is the task implementation itself and in the case of <style> it is the implementation of the org.apache.tools.ant.taskdefs.XSLTLiaison class. Ant's class loader implementation uses Java's delegation model, see http://java.sun.com/products/jdk/1.2/docs/api/java/lang/ClassLoader.html the paragraph > The ClassLoader class uses a delegation model to search for classes and > resources. Each instance of ClassLoader has an associated parent class loader. > When called upon to find a class or resource, a ClassLoader instance will > delegate the search for the class or resource to its parent class loader > before attempting to find the class or resource itself. The virtual machine's > built-in class loader, called the bootstrap class loader, does not itself have > a parent but may serve as the parent of a ClassLoader instance. This means, Ant's class loader will consult the bootstrap class loader first, which tries to load classes from CLASSPATH. The bootstrap class loader doesn't know anything about Ant's class loader or even the path you have specified. If the bootstrap class loader can load the class Ant has asked it to load, this class will try to load the external library from CLASSPATH as well - it doesn't know anything else - and will not find it unless the library is in CLASSPATH as well. To solve this, you have two major options: (1) put all external libaries you need in CLASSPATH as well this is not what you want, otherwise you wouldn't have found this bug report. (2) remove the class that loads the external library from the CLASSPATH. The easiest way to do this is to remove optional.jar from ANT_HOME. If you do so, you will have to <taskdef> all optional tasks and use nested <classpath> elements in the <taskdef> tasks that point to the new location of optional.jar. Also, don't forget to add the new location of optional.jar to the <classpath> of your <style> or <junit> task. If you want to avoid to <taskdef> all optional tasks you need, the only other option is to remove the classes that should not be loaded via the bootstrap class loader from optional.jar and put them into a separate archive. Add this separate archive to the <classpath> of your <style> or <junit> task - and make sure the separate archive is not in CLASSPATH. In the case of <junit> you'd have to remove all classes that are in the org/apache/tools/ant/taskdefs/optional/junit directory, in the <style> case it is one of the *Liaison classes in org/apache/tools/ant/taskdefs/optional. If you use the option to break up optional.jar for <junit>, you still have to use a <taskdef> with a nested <classpath> to define the junit task. Does this description make any sense? Would it help people who face the same problem you have seen? If not, how can we improve it? -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
