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 <mgit...@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 <vimils...@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 <mgit...@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. > >