You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@ant.apache.org by Mitch Gitman <mg...@gmail.com> on 2012/06/01 04:16:02 UTC

Re: example of correctly consuming an Ant project programmatically

Nicolas, thanks. I think this is what I'm looking for.

Here's the relevant passage from Launcher:
        URL[] jars = getJarArray(
            libURLs, userURLs, systemURLs, Locator.getToolsJar());
…
        URLClassLoader loader = new URLClassLoader(jars);
        Thread.currentThread().setContextClassLoader(loader);
        Class mainClass = null;
        int exitCode = 0;
        try {
            mainClass = loader.loadClass(mainClassname);
            AntMain main = (AntMain) mainClass.newInstance();
            main.startAnt(newArgs, null, null);
        } catch (InstantiationException ex) {

The one way I may have to tweak this (well, aside from instantiating
Project directly instead of Main) is to do:
new URLClassLoader(jars, null);

Passing null for the extra ClassLoader argument obviates the possibility of
the parent classloader creeping in.

I went looking for how AntUnit initializes the Ant Project, and
interestingly, it does something not unlike what I was doing. No
controlling of the ClassLoader. I suppose the existing ClassLoader for
AntUnit, already normally being invoked by Ant, suffices.

I also opened up the Manning "Ant in Action" book and came across a whole
section on "Embedding Ant." Same story. And again, that seems to suffice,
considering here's how the Java class containing the embedded Ant is being
invoked:
<target name="exec" >
    <java classname="org.antbook.embed.Embedded"
        failonerror="true"
        fork="true">
        <classpath>
            <pathelement path="${target.jar}" />
            <pathelement path="${java.class.path}" />
        </classpath>
    </java>
</target>

Notice the use of java.class.path. I see that this gives me the contents of
the ANT_HOME/lib directory. So (as long as my test is being invoked via
Ant) the combination of java.class.path and Locator.getToolsJar() should be
everything I need for the embedded Ant classpath.

Still, if anyone can point to an example implementation (of which there
must be a few out there), that would be great.

On Thu, May 31, 2012 at 2:17 PM, Nicolas Lalevée <nicolas.lalevee@hibnet.org
> wrote:

>
> Le 31 mai 2012 à 18:33, Mitch Gitman a écrit :
>
> > Can someone point me to a good, reference example of consuming an Ant
> > project programmatically? The code needs to have access to the
> > org.apache.tools.ant.Project object.
> >
> > I have been able to do this, but with just one catch. Below are the
> > relevant lines of Java code:
> > Project project = new Project();
> > project.setBaseDir(basedir); // basedir is a File object
> > project.init();
> > ProjectHelper.configureProject(project, buildFile); // buildFile is a
> File
> > object
> >
> > From here, I can call executeTarget on the Project object as needed.
> >
> > Everything works fine, but here's the catch. Whatever the code is that
> > instantiates the Project object, the Project will take the libraries in
> the
> > classpath for that code (typically a JUnit test) and put that in its own
> > classpath.
> >
> > So, for example, if the programmatically instantiated Ant needs to call
> the
> > javac Ant task, then I would need to add lib/tools.jar in the JDK to the
> > runtime classpath for the code that launches Ant. Likewise, there might
> be
> > some libraries that are needed in the test's classpath but aren't needed
> by
> > the Ant project that is launched by the test but which will then leak
> into
> > the Project's classpath and wreak havoc.
> >
> > My guess is there's something about the coreLoader member of the Project
> > object I need to be controlling. I've also looked at the AntClassLoader
> > class. My fear is there's something really fundamental about the Ant
> > ClassLoader, or maybe just ClassLoaders in general, that I'm not quite
> > grasping.
> >
> > This is where it would be great if there's an existing, isolated example
> of
> > creating a Project that has the expected JARs in Ant lib plus tools.jar
> but
> > nothing more. This seems like the kind of thing that people have had to
> do
> > countless times before.
>
> You have indeed to properly setup the classloader used by the Project. If
> you want to setup a classloader like the one which is used at the boostrap
> of Ant, when it is picking up jars in the .ant/lib folder for instance, and
> also the tools.jar (see when Locator.getToolsJar() is called), you should
> look into the code of org.apache.tools.ant.launch.Launcher.run(String[]).
>
> I have never played with an AntClassLoader, but probably a classical
> URLClassloader will work just fine.
>
> Nicolas
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
> For additional commands, e-mail: user-help@ant.apache.org
>
>