ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Vimil Saju <vimils...@yahoo.com>
Subject Re: controlling ClassLoader when programmatically invoking Ant
Date Sun, 22 Jul 2012 19:46:13 GMT
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 <mgitman@gmail.com>
To: Ant Developers List <dev@ant.apache.org> 
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 <vimilsaju@yahoo.com> 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 <mgitman@gmail.com>
> To: Ant Developers List <dev@ant.apache.org>
> 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.
>
>
Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message