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/05/31 18:33:03 UTC
example of correctly consuming an Ant project programmatically
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.
Re: example of correctly consuming an Ant project programmatically
Posted by Mitch Gitman <mg...@gmail.com>.
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
>
>
Re: example of correctly consuming an Ant project programmatically
Posted by Nicolas Lalevée <ni...@hibnet.org>.
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