Re: controlling ClassLoader when programmatically invoking Ant

2012-07-22 Thread Vimil Saju
I'll probably have to see some code to understand what's going on, but 
reflection will prevent classcast exceptions when accessing methods of a class 
loaded from a different class loader. 



 From: Mitch Gitman 
To: Ant Developers List  
Sent: Sunday, July 22, 2012 8:52 AM
Subject: Re: controlling ClassLoader when programmatically invoking Ant
 
Right, what you describe falls under the #1 option I'd mentioned:
"1. Create a parent ClassLoader just for all the Ant libraries and put
JUnit itself and the entire test classpath in a child classloader."

Considering that the code in question consists of JUnit tests that I WANT
to run from within an IDE and that I NEED to run from Ant, together with
producing the customary reports, this could get complicated pretty fast.

Right now, I'm pursuing my option #3, the complications for which are:
* Creating a URLClassLoader that uses a scaled-down analog to the Launcher
URLClassLoader.
* Deploying a JAR containing nothing but the custom BuildListener and
BuildLogger to Ant lib.
* Accessing the Project and custom BuildListener and BuildLogger using
strictly reflection in the Ant test runner code.

On Sun, Jul 22, 2012 at 5:27 AM, Vimil Saju  wrote:

> >So this time I actually did this. I created this parentless ClassLoader
> and
> >created a Project object from it. And what happened? The moment I tried to
> >assign this object to a Project variable, I got a ClassCastException:
> >org.apache.tools.ant.Project cannot be cast to
> >org.apache.tools.ant.Project. So it's sort of a chicken-and-egg problem.
>
>
> I think to prevent class-cast issue, you should first create a class with
> just a static main method, then use the parentless class loader to create
> an instance of this class and invoke its main method through reflection.
>  All the ant related code should be then written in then main method of
> the class that you created.
>
> The reason you are getting the class-cast exception is because you are
> creating the Project object using say classloaderA and then trying to
> access that object from a class that was loaded from another classloader.
>
>
> 
>  From: Mitch Gitman 
> To: Ant Developers List 
> Sent: Saturday, July 21, 2012 6:16 PM
> Subject: Re: controlling ClassLoader when programmatically invoking Ant
>
> Quick update for anyone who's curious.
>
> I'd forgotten that I'd asked much the same question on the ant-user list
> back on May 31. This was back when the contamination of the child classpath
> with the parent classpath was literally causing the tests to fail. And same
> as with this thread, Nicolas L. was kind enough to respond. See thread,
> "example of correctly consuming an Ant project programmatically."
>
> What's funny (and sad in a way) is that today I went down much the same
> path I had laid in the earlier thread without even recollecting that
> thread. Here's what I wrote earlier:
> ***
> The one way I may have to tweak this ... is to do:
> new URLClassLoader(jars, null);
>
> Passing null for the extra ClassLoader argument obviates the possibility of
> the parent classloader creeping in.
> ***
> So this time I actually did this. I created this parentless ClassLoader and
> created a Project object from it. And what happened? The moment I tried to
> assign this object to a Project variable, I got a ClassCastException:
> org.apache.tools.ant.Project cannot be cast to
> org.apache.tools.ant.Project. So it's sort of a chicken-and-egg problem.
>
> I also tried just calling Project.setCoreLoader() with this URLClassLoader,
> but that didn't change the way the Ivy JAR and such were being loaded.
>
> At this point, I can think of a few ways to address this problem:
> 1. Create a parent ClassLoader just for all the Ant libraries and put JUnit
> itself and the entire test classpath in a child classloader.
> 2. Run the Launcher class with the sandboxed ClassLoader and have a build
> listener and build logger write the messages and out/err to the filesystem.
> Then to do the assertions, read the files after the fact.
> 3. Obtain an Object instance rather than a Project instance and use
> reflection to call the few methods I have to call on it.
>
> #1 scares me! #2 is defeating much of the purpose of doing all this
> programmatically. #3 ain't pretty, but so far it seems doable.
>
>

Re: controlling ClassLoader when programmatically invoking Ant

2012-07-22 Thread Mitch Gitman
Right, what you describe falls under the #1 option I'd mentioned:
"1. Create a parent ClassLoader just for all the Ant libraries and put
JUnit itself and the entire test classpath in a child classloader."

Considering that the code in question consists of JUnit tests that I WANT
to run from within an IDE and that I NEED to run from Ant, together with
producing the customary reports, this could get complicated pretty fast.

Right now, I'm pursuing my option #3, the complications for which are:
* Creating a URLClassLoader that uses a scaled-down analog to the Launcher
URLClassLoader.
* Deploying a JAR containing nothing but the custom BuildListener and
BuildLogger to Ant lib.
* Accessing the Project and custom BuildListener and BuildLogger using
strictly reflection in the Ant test runner code.

On Sun, Jul 22, 2012 at 5:27 AM, Vimil Saju  wrote:

> >So this time I actually did this. I created this parentless ClassLoader
> and
> >created a Project object from it. And what happened? The moment I tried to
> >assign this object to a Project variable, I got a ClassCastException:
> >org.apache.tools.ant.Project cannot be cast to
> >org.apache.tools.ant.Project. So it's sort of a chicken-and-egg problem.
>
>
> I think to prevent class-cast issue, you should first create a class with
> just a static main method, then use the parentless class loader to create
> an instance of this class and invoke its main method through reflection.
>  All the ant related code should be then written in then main method of
> the class that you created.
>
> The reason you are getting the class-cast exception is because you are
> creating the Project object using say classloaderA and then trying to
> access that object from a class that was loaded from another classloader.
>
>
> 
>  From: Mitch Gitman 
> To: Ant Developers List 
> Sent: Saturday, July 21, 2012 6:16 PM
> Subject: Re: controlling ClassLoader when programmatically invoking Ant
>
> Quick update for anyone who's curious.
>
> I'd forgotten that I'd asked much the same question on the ant-user list
> back on May 31. This was back when the contamination of the child classpath
> with the parent classpath was literally causing the tests to fail. And same
> as with this thread, Nicolas L. was kind enough to respond. See thread,
> "example of correctly consuming an Ant project programmatically."
>
> What's funny (and sad in a way) is that today I went down much the same
> path I had laid in the earlier thread without even recollecting that
> thread. Here's what I wrote earlier:
> ***
> The one way I may have to tweak this ... is to do:
> new URLClassLoader(jars, null);
>
> Passing null for the extra ClassLoader argument obviates the possibility of
> the parent classloader creeping in.
> ***
> So this time I actually did this. I created this parentless ClassLoader and
> created a Project object from it. And what happened? The moment I tried to
> assign this object to a Project variable, I got a ClassCastException:
> org.apache.tools.ant.Project cannot be cast to
> org.apache.tools.ant.Project. So it's sort of a chicken-and-egg problem.
>
> I also tried just calling Project.setCoreLoader() with this URLClassLoader,
> but that didn't change the way the Ivy JAR and such were being loaded.
>
> At this point, I can think of a few ways to address this problem:
> 1. Create a parent ClassLoader just for all the Ant libraries and put JUnit
> itself and the entire test classpath in a child classloader.
> 2. Run the Launcher class with the sandboxed ClassLoader and have a build
> listener and build logger write the messages and out/err to the filesystem.
> Then to do the assertions, read the files after the fact.
> 3. Obtain an Object instance rather than a Project instance and use
> reflection to call the few methods I have to call on it.
>
> #1 scares me! #2 is defeating much of the purpose of doing all this
> programmatically. #3 ain't pretty, but so far it seems doable.
>
>


Re: controlling ClassLoader when programmatically invoking Ant

2012-07-22 Thread Vimil Saju
>So this time I actually did this. I created this parentless ClassLoader and
>created a Project object from it. And what happened? The moment I tried to
>assign this object to a Project variable, I got a ClassCastException:
>org.apache.tools.ant.Project cannot be cast to
>org.apache.tools.ant.Project. So it's sort of a chicken-and-egg problem.


I think to prevent class-cast issue, you should first create a class with just 
a static main method, then use the parentless class loader to create an 
instance of this class and invoke its main method through reflection.
 All the ant related code should be then written in then main method of the 
class that you created.

The reason you are getting the class-cast exception is because you are creating 
the Project object using say classloaderA and then trying to access that object 
from a class that was loaded from another classloader. 



 From: Mitch Gitman 
To: Ant Developers List  
Sent: Saturday, July 21, 2012 6:16 PM
Subject: Re: controlling ClassLoader when programmatically invoking Ant
 
Quick update for anyone who's curious.

I'd forgotten that I'd asked much the same question on the ant-user list
back on May 31. This was back when the contamination of the child classpath
with the parent classpath was literally causing the tests to fail. And same
as with this thread, Nicolas L. was kind enough to respond. See thread,
"example of correctly consuming an Ant project programmatically."

What's funny (and sad in a way) is that today I went down much the same
path I had laid in the earlier thread without even recollecting that
thread. Here's what I wrote earlier:
***
The one way I may have to tweak this ... is to do:
new URLClassLoader(jars, null);

Passing null for the extra ClassLoader argument obviates the possibility of
the parent classloader creeping in.
***
So this time I actually did this. I created this parentless ClassLoader and
created a Project object from it. And what happened? The moment I tried to
assign this object to a Project variable, I got a ClassCastException:
org.apache.tools.ant.Project cannot be cast to
org.apache.tools.ant.Project. So it's sort of a chicken-and-egg problem.

I also tried just calling Project.setCoreLoader() with this URLClassLoader,
but that didn't change the way the Ivy JAR and such were being loaded.

At this point, I can think of a few ways to address this problem:
1. Create a parent ClassLoader just for all the Ant libraries and put JUnit
itself and the entire test classpath in a child classloader.
2. Run the Launcher class with the sandboxed ClassLoader and have a build
listener and build logger write the messages and out/err to the filesystem.
Then to do the assertions, read the files after the fact.
3. Obtain an Object instance rather than a Project instance and use
reflection to call the few methods I have to call on it.

#1 scares me! #2 is defeating much of the purpose of doing all this
programmatically. #3 ain't pretty, but so far it seems doable.

On Sat, Jul 21, 2012 at 9:33 AM, Mitch Gitman  wrote:

> Nicolas, thanks. I was one class off. I was looking at Main and AntMain
> when I should have been looking at Launcher. Seeing the type names and the
> main method threw me off. And this corroborates my brief follow-up that I
> could be doing something with URLClassLoader. Better for me to try to
> leverage Launcher though than reinvent that wheel.
>
> Let me see how far I get with that.
>
> I do have to take issue with the one point you make: "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."
>
> First, this is not a unit test. It's an integration test or a functional
> test, and if it doesn't emulate the real-life behavior in the wild, then
> what use is it?
>
> Even if we are treating this as a unit test, you can't really say that
> inadvertently picking up everything in the parent ClassLoader is the
> equivalent of mocking or stubbing services and components as one normally
> does when creating pure unit tests. Consider that there could be a ton of
> classes in the IDE's ClassLoader that have nothing whatsoever to do with
> the Ant Project being executed.
>
> And this brings me to my last concern. I have already encountered a
> problem where some static functionality in some superfluous classes in the
> IDE-inherited ClassLoader was causing the JUnit-invoked Project build to
> fail.
>
> Even so, to my mind, the uncontrolled success I'm seeing now is no less
> troubling than the uncontrolled failure I was seeing then. If you're a
> biologist conducting an experiment, you don't want to find out your
> cultures

Re: controlling ClassLoader when programmatically invoking Ant

2012-07-21 Thread Mitch Gitman
Quick update for anyone who's curious.

I'd forgotten that I'd asked much the same question on the ant-user list
back on May 31. This was back when the contamination of the child classpath
with the parent classpath was literally causing the tests to fail. And same
as with this thread, Nicolas L. was kind enough to respond. See thread,
"example of correctly consuming an Ant project programmatically."

What's funny (and sad in a way) is that today I went down much the same
path I had laid in the earlier thread without even recollecting that
thread. Here's what I wrote earlier:
***
The one way I may have to tweak this ... is to do:
new URLClassLoader(jars, null);

Passing null for the extra ClassLoader argument obviates the possibility of
the parent classloader creeping in.
***
So this time I actually did this. I created this parentless ClassLoader and
created a Project object from it. And what happened? The moment I tried to
assign this object to a Project variable, I got a ClassCastException:
org.apache.tools.ant.Project cannot be cast to
org.apache.tools.ant.Project. So it's sort of a chicken-and-egg problem.

I also tried just calling Project.setCoreLoader() with this URLClassLoader,
but that didn't change the way the Ivy JAR and such were being loaded.

At this point, I can think of a few ways to address this problem:
1. Create a parent ClassLoader just for all the Ant libraries and put JUnit
itself and the entire test classpath in a child classloader.
2. Run the Launcher class with the sandboxed ClassLoader and have a build
listener and build logger write the messages and out/err to the filesystem.
Then to do the assertions, read the files after the fact.
3. Obtain an Object instance rather than a Project instance and use
reflection to call the few methods I have to call on it.

#1 scares me! #2 is defeating much of the purpose of doing all this
programmatically. #3 ain't pretty, but so far it seems doable.

On Sat, Jul 21, 2012 at 9:33 AM, Mitch Gitman  wrote:

> Nicolas, thanks. I was one class off. I was looking at Main and AntMain
> when I should have been looking at Launcher. Seeing the type names and the
> main method threw me off. And this corroborates my brief follow-up that I
> could be doing something with URLClassLoader. Better for me to try to
> leverage Launcher though than reinvent that wheel.
>
> Let me see how far I get with that.
>
> I do have to take issue with the one point you make: "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."
>
> First, this is not a unit test. It's an integration test or a functional
> test, and if it doesn't emulate the real-life behavior in the wild, then
> what use is it?
>
> Even if we are treating this as a unit test, you can't really say that
> inadvertently picking up everything in the parent ClassLoader is the
> equivalent of mocking or stubbing services and components as one normally
> does when creating pure unit tests. Consider that there could be a ton of
> classes in the IDE's ClassLoader that have nothing whatsoever to do with
> the Ant Project being executed.
>
> And this brings me to my last concern. I have already encountered a
> problem where some static functionality in some superfluous classes in the
> IDE-inherited ClassLoader was causing the JUnit-invoked Project build to
> fail.
>
> Even so, to my mind, the uncontrolled success I'm seeing now is no less
> troubling than the uncontrolled failure I was seeing then. If you're a
> biologist conducting an experiment, you don't want to find out your
> cultures were growing only because the Petri dish got contaminated.
>
> On Sat, Jul 21, 2012 at 6:10 AM, Nicolas Lalevée <
> nicolas.lale...@hibnet.org> wrote:
>
>> 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:
>> > > > default="build">
>> >
>> >
>> >
>> >
>> >
>> > 
>> >
>> > I've abbreviated the

Re: controlling ClassLoader when programmatically invoking Ant

2012-07-21 Thread Mitch Gitman
Nicolas, thanks. I was one class off. I was looking at Main and AntMain
when I should have been looking at Launcher. Seeing the type names and the
main method threw me off. And this corroborates my brief follow-up that I
could be doing something with URLClassLoader. Better for me to try to
leverage Launcher though than reinvent that wheel.

Let me see how far I get with that.

I do have to take issue with the one point you make: "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."

First, this is not a unit test. It's an integration test or a functional
test, and if it doesn't emulate the real-life behavior in the wild, then
what use is it?

Even if we are treating this as a unit test, you can't really say that
inadvertently picking up everything in the parent ClassLoader is the
equivalent of mocking or stubbing services and components as one normally
does when creating pure unit tests. Consider that there could be a ton of
classes in the IDE's ClassLoader that have nothing whatsoever to do with
the Ant Project being executed.

And this brings me to my last concern. I have already encountered a problem
where some static functionality in some superfluous classes in the
IDE-inherited ClassLoader was causing the JUnit-invoked Project build to
fail.

Even so, to my mind, the uncontrolled success I'm seeing now is no less
troubling than the uncontrolled failure I was seeing then. If you're a
biologist conducting an experiment, you don't want to find out your
cultures were growing only because the Petri dish got contaminated.

On Sat, Jul 21, 2012 at 6:10 AM, Nicolas Lalevée  wrote:

> 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:
> >  > default="build">
> >
> >
> >
> >
> >
> > 
> >
> > 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

Re: controlling ClassLoader when programmatically invoking Ant

2012-07-21 Thread Nicolas Lalevée
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:
>  default="build">
> 
>
>
>
>
> 
> 
> 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



Re: controlling ClassLoader when programmatically invoking Ant

2012-07-20 Thread Mitch Gitman
P.S. I'm going to give URLClassLoader a shot with the JARs in Ant lib:
http://docs.oracle.com/javase/6/docs/api/java/net/URLClassLoader.html

Almost sounds a little too easy...

On Fri, Jul 20, 2012 at 10:37 PM, Mitch Gitman  wrote:

> 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")
>
> 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:
>  default="build">
>
> 
> 
> 
> 
> 
>
> 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.
>
> 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
> ...
>
> 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.
>
> If someone's going to say, "Hey, check what antunit does," I'd appreciate
> if you could pinpoint what it's doing.
>
> P.S. Perhaps somebody has a rational explanation too for why the taskdef
> of Ivy is creeping in.
>


controlling ClassLoader when programmatically invoking Ant

2012-07-20 Thread Mitch Gitman
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")

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:








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.

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
...

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.

If someone's going to say, "Hey, check what antunit does," I'd appreciate
if you could pinpoint what it's doing.

P.S. Perhaps somebody has a rational explanation too for why the taskdef of
Ivy is creeping in.