PR: 6606 git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272510 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -288,6 +288,10 @@ | |||
| </a></li> | |||
| <li><a href="#javadoc-cannot-execute"> | |||
| JavaDoc failed: java.io.IOException: javadoc: cannot execute | |||
| </a></li> | |||
| <li><a href="#delegating-classloader"> | |||
| <style> or <junit> ignores my | |||
| <classpath> | |||
| </a></li> | |||
| </ul> | |||
| </blockquote> | |||
| @@ -1873,6 +1877,113 @@ mv /tmp/foo $ANT_HOME/bin/antRun | |||
| </blockquote> | |||
| </td></tr> | |||
| </table> | |||
| </a> | |||
| <a name="delegating-classloader"> | |||
| <table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||
| <tr><td bgcolor="#828DA6"> | |||
| <font color="#ffffff" face="arial,helvetica,sanserif"> | |||
| <strong> | |||
| <style> or <junit> ignores my | |||
| <classpath> | |||
| </strong> | |||
| </font> | |||
| </td></tr> | |||
| <tr><td> | |||
| <blockquote> | |||
| <p>These tasks don't ignore your classpath setting, you | |||
| are facing a common problem with delegating classloaders.</p> | |||
| <p>First of all let's state that Ant adds all | |||
| <code>.jar</code> files from <code>ANT_HOME/lib</code> to | |||
| <code>CLASSPATH</code>, therefore "in | |||
| <code>CLASSPATH</code>" shall mean "either in your | |||
| <code>CLASSPATH</code> environment variable or | |||
| <code>ANT_HOME/lib</code>" for the rest of this | |||
| answer.</p> | |||
| <p>This question 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 | |||
| <code>CLASSPATH</code>.</p> | |||
| <p>The root of the problem is that the class that needs the | |||
| external library is on the <code>CLASSPATH</code>.</p> | |||
| <p>When you specify a nested <code><classpath></code> 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.</p> | |||
| <p>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.</p> | |||
| <p>In the case of <code><junit></code> it is the task | |||
| implementation itself and in the case of | |||
| <code><style></code> it is the implementation of the | |||
| <code>org.apache.tools.ant.taskdefs.XSLTLiaison</code> | |||
| class.</p> | |||
| <p>Ant's class loader implementation uses Java's | |||
| delegation model, see <a href="http://java.sun.com/products/jdk/1.2/docs/api/java/lang/ClassLoader.html">http://java.sun.com/products/jdk/1.2/docs/api/java/lang/ClassLoader.html</a> | |||
| the paragraph</p> | |||
| <blockquote>The <code>ClassLoader</code> class uses a | |||
| delegation model to search for classes and resources. Each | |||
| instance of <code>ClassLoader</code> has an associated parent | |||
| class loader. When called upon to find a class or resource, a | |||
| <code>ClassLoader</code> 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 <code>ClassLoader</code> | |||
| instance.</blockquote> | |||
| <p>This means, Ant's class loader will consult the | |||
| bootstrap class loader first, which tries to load classes from | |||
| <code>CLASSPATH</code>. The bootstrap class loader | |||
| doesn't know anything about Ant's class loader or | |||
| even the path you have specified.</p> | |||
| <p>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 <code>CLASSPATH</code> as well - it doesn't | |||
| know anything else - and will not find it unless the library | |||
| is in <code>CLASSPATH</code> as well.</p> | |||
| <p>To solve this, you have two major options:</p> | |||
| <ol> | |||
| <li>put all external libaries you need in | |||
| <code>CLASSPATH</code> as well this is not what you want, | |||
| otherwise you wouldn't have found this FAQ entry.</li> | |||
| <li>remove the class that loads the external library from | |||
| the <code>CLASSPATH</code>.</li> | |||
| </ol> | |||
| <p>The easiest way to do this is to remove | |||
| <code>optional.jar</code> from <code>ANT_HOME/lib</code>. If | |||
| you do so, you will have to <code><taskdef></code> all | |||
| optional tasks and use nested <code><classpath></code> | |||
| elements in the <code><taskdef></code> tasks that point | |||
| to the new location of <code>optional.jar</code>. Also, | |||
| don't forget to add the new location of | |||
| <code>optional.jar</code> to the | |||
| <code><classpath></code> of your | |||
| <code><style></code> or <code><junit></code> | |||
| task.</p> | |||
| <p>If you want to avoid to <code><taskdef></code> 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 <code>optional.jar</code> and put them into a | |||
| separate archive. Add this separate archive to the | |||
| <code><classpath></code> of your | |||
| <code><style></code> or <code><junit></code> task | |||
| - and make sure the separate archive is not in | |||
| <code>CLASSPATH</code>.</p> | |||
| <p>In the case of <code><junit></code> you'd have | |||
| to remove all classes that are in the | |||
| <code>org/apache/tools/ant/taskdefs/optional/junit</code> | |||
| directory, in the <code><style></code> case it is one of | |||
| the <code>*Liaison</code> classes in | |||
| <code>org/apache/tools/ant/taskdefs/optional</code>.</p> | |||
| <p>If you use the option to break up <code>optional.jar</code> | |||
| for <code><junit></code>, you still have to use a | |||
| <code><taskdef></code> with a nested | |||
| <code><classpath></code> to define the junit task.</p> | |||
| </blockquote> | |||
| </td></tr> | |||
| </table> | |||
| </a> | |||
| </blockquote> | |||
| </td></tr> | |||
| @@ -34,8 +34,8 @@ include their locations in your <code>CLASSPATH</code> environment variable. | |||
| Do neither of the above, and instead, specify their locations using | |||
| a <code><classpath></code> element in the build file. | |||
| See <a href="http://nagoya.apache.org/bugzilla/show_bug.cgi?id=6606">the | |||
| bugs database</a> for details. | |||
| See <a href="../../faq.html#delegating-classloader" target="_top">the | |||
| FAQ</a> for details. | |||
| </ol> | |||
| </p> | |||
| @@ -951,6 +951,122 @@ mv /tmp/foo $ANT_HOME/bin/antRun | |||
| the front of the PATH fixes the problem.</p> | |||
| </answer> | |||
| </faq> | |||
| <faq id="delegating-classloader"> | |||
| <question><style> or <junit> ignores my | |||
| <classpath></question> | |||
| <answer> | |||
| <p>These tasks don't ignore your classpath setting, you | |||
| are facing a common problem with delegating classloaders.</p> | |||
| <p>First of all let's state that Ant adds all | |||
| <code>.jar</code> files from <code>ANT_HOME/lib</code> to | |||
| <code>CLASSPATH</code>, therefore "in | |||
| <code>CLASSPATH</code>" shall mean "either in your | |||
| <code>CLASSPATH</code> environment variable or | |||
| <code>ANT_HOME/lib</code>" for the rest of this | |||
| answer.</p> | |||
| <p>This question 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 | |||
| <code>CLASSPATH</code>.</p> | |||
| <p>The root of the problem is that the class that needs the | |||
| external library is on the <code>CLASSPATH</code>.</p> | |||
| <p>When you specify a nested <code><classpath></code> 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.</p> | |||
| <p>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.</p> | |||
| <p>In the case of <code><junit></code> it is the task | |||
| implementation itself and in the case of | |||
| <code><style></code> it is the implementation of the | |||
| <code>org.apache.tools.ant.taskdefs.XSLTLiaison</code> | |||
| class.</p> | |||
| <p>Ant's class loader implementation uses Java's | |||
| delegation model, see <a | |||
| href="http://java.sun.com/products/jdk/1.2/docs/api/java/lang/ClassLoader.html">http://java.sun.com/products/jdk/1.2/docs/api/java/lang/ClassLoader.html</a> | |||
| the paragraph</p> | |||
| <blockquote>The <code>ClassLoader</code> class uses a | |||
| delegation model to search for classes and resources. Each | |||
| instance of <code>ClassLoader</code> has an associated parent | |||
| class loader. When called upon to find a class or resource, a | |||
| <code>ClassLoader</code> 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 <code>ClassLoader</code> | |||
| instance.</blockquote> | |||
| <p>This means, Ant's class loader will consult the | |||
| bootstrap class loader first, which tries to load classes from | |||
| <code>CLASSPATH</code>. The bootstrap class loader | |||
| doesn't know anything about Ant's class loader or | |||
| even the path you have specified.</p> | |||
| <p>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 <code>CLASSPATH</code> as well - it doesn't | |||
| know anything else - and will not find it unless the library | |||
| is in <code>CLASSPATH</code> as well.</p> | |||
| <p>To solve this, you have two major options:</p> | |||
| <ol> | |||
| <li>put all external libaries you need in | |||
| <code>CLASSPATH</code> as well this is not what you want, | |||
| otherwise you wouldn't have found this FAQ entry.</li> | |||
| <li>remove the class that loads the external library from | |||
| the <code>CLASSPATH</code>.</li> | |||
| </ol> | |||
| <p>The easiest way to do this is to remove | |||
| <code>optional.jar</code> from <code>ANT_HOME/lib</code>. If | |||
| you do so, you will have to <code><taskdef></code> all | |||
| optional tasks and use nested <code><classpath></code> | |||
| elements in the <code><taskdef></code> tasks that point | |||
| to the new location of <code>optional.jar</code>. Also, | |||
| don't forget to add the new location of | |||
| <code>optional.jar</code> to the | |||
| <code><classpath></code> of your | |||
| <code><style></code> or <code><junit></code> | |||
| task.</p> | |||
| <p>If you want to avoid to <code><taskdef></code> 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 <code>optional.jar</code> and put them into a | |||
| separate archive. Add this separate archive to the | |||
| <code><classpath></code> of your | |||
| <code><style></code> or <code><junit></code> task | |||
| - and make sure the separate archive is not in | |||
| <code>CLASSPATH</code>.</p> | |||
| <p>In the case of <code><junit></code> you'd have | |||
| to remove all classes that are in the | |||
| <code>org/apache/tools/ant/taskdefs/optional/junit</code> | |||
| directory, in the <code><style></code> case it is one of | |||
| the <code>*Liaison</code> classes in | |||
| <code>org/apache/tools/ant/taskdefs/optional</code>.</p> | |||
| <p>If you use the option to break up <code>optional.jar</code> | |||
| for <code><junit></code>, you still have to use a | |||
| <code><taskdef></code> with a nested | |||
| <code><classpath></code> to define the junit task.</p> | |||
| </answer> | |||
| </faq> | |||
| </faqsection> | |||
| </document> | |||