Hi Mitch,

Le 21 juil. 2012 à 07:37, Mitch Gitman a écrit :

> Technically, this message is better suited for the ant-user list, but I'm
> thinking I'm more apt to get an answer on this list. (I'm also thinking
> this is the better place for me to cash in some chits for my having
> submitted patches for three Ivy issues I mentioned recently on this list.
> Subject: "extends and buildlist on 2.3.0-rc1....")

I am intended to give it a look very soon, I have seen all the activity you 
have done, I don't want to waste it :)

> Here's my problem. I'm trying to do a JUnit test of some Ivy functionality
> (actually, relating to the aforementioned Ivy bugs) by programmatically
> creating and executing an Ant Project object. Everything runs just fine.
> I'm able to execute targets and even tie in a BuildListener and a
> BuildLogger to tap into output and error and check if the build failed.
> 
> The problem is, everything works a little too well. Take a look at the
> following example build.xml:
> <project xmlns:ivy="antlib:org.apache.ivy.ant" name="resolve-test"
> default="build">
> 
>    <target name="build">
>    <ivy:settings file="ivysettings.xml" />
>    <ivy:resolve ... />
>    </target>
> </project>
> 
> I've abbreviated the ivy:resolve call, but take it from me that everything
> works, including running the test directly from within an IDE. It
> shouldn't. Nowhere am I specifying the classpath containing the JAR for Ivy
> itself. Nowhere am I even doing the taskdef for Ivy.

In fact, just by writing xmlns:ivy="antlib:org.apache.ivy.ant", Ant does a 
lookup for the Ivy tasks. It will look for org/apache/ivy/ant/antlib.xml in the 
classpath, derived from the uri definition of the xmlns.
So I guess that in your IDE, it works since you have Ivy in your classpath.

> And in fact, if I run this build.xml straight from the command line, it
> fails like you would expect:
> Problem: failed to create task or type antlib:org.apache.ivy.ant:settings
> ...

This means that the Ivy jar is neither in the Ant classpath ($ANT_HOME/lib/), 
nor in your ant user lib directory ($HOME/.ant/lib).

> I can only think that the key method I want to take advantage of is this in
> Project:
>    public void setCoreLoader(ClassLoader coreLoader) {
>        this.coreLoader = coreLoader;
>    }
> 
> What's interesting is that the command-line entry point for Ant in
> org.apache.tools.ant.Main ends up passing null to setCoreLoader, in which
> case "the parent classloader should be used," according to the method's
> Javadoc. At this point, I go take a look at the scripts that launch Ant and
> my eyes get blurry. But I believe what I want to do is manually construct a
> ClassLoader as if I were running "java -cp ..." with the contents of Ant's
> lib directory. (I'm showing my ignorance of ClassLoaders here, I realize.)
> Perhaps someone can point me to an elegant way to accomplish that.

On the command line, the jvm is given only the ant-launcher.jar, it will be the 
content of the system classloader.
Then in org.apache.tools.ant.launch.Launcher.run(String[]), we can see the ant 
Main class is loaded and launched with this classloader:
new URLClassLoader(jars, Launcher.class.getClassLoader());
The system is the parent, the jars listed from $ANT_HOME/lib/, $HOME/.ant/lib 
and other jars from the jvm (tools.jar for instance) will be the content of 
that classloader. This last classloader will be the parent classloader of the 
Project instance.

Now in your IDE, you launch your unit test with every jar listed in your 
classpath, so every thing is already available in the system classlaoder. And 
that system classloader is the parent classloader of the Project instance. So 
lookups works.
So if you want thing to not work, you'll have to build indeed an 
URLClassloader, just like org.apache.tools.ant.launch.Launcher.run does. But 
without any parent classlaoder, otherwise you end up again with the full 
classpath of your project in the IDE.

But If I were you, I wouldn't bother trying to mimic Ant classloading in a unit 
test. The important thing is to be sure that you run against the expected 
version of Ant and Ivy. And relying on the content of a $HOME/.ant/lib is quite 
unsafe.

Nicolas


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@ant.apache.org
For additional commands, e-mail: dev-h...@ant.apache.org

Reply via email to