Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Invoking Apache Ant programmatically

Making use of Ant buildfiles from within your Java code

Nell Gawor (ngawor@us.ibm.com), Advisory Software Engineer, IBM
Nell Gawor is an advisory software engineer for IBM in Research Triangle Park, North Carolina, in the Software Group Advanced Design and Technology Group. She received a Masters Degree in Computer Science from the University of Illinois at Urbana-Champaign. Contact Nell at ngawor@us.ibm.com.

Summary:  This article demonstrates how to invoke Apache Ant buildfiles via Java. You will examine the necessary Java code and see how to run this code within WebSphere Application Developer.

Date:  09 Feb 2005
Level:  Introductory

Activity:  34175 views
Comments:  

Introduction

Apache Ant is an open-source Java-based build utility. It is often compared to Make, which has long been used to help automate the build process. As Ant has progressed through various versions, it has developed a rich library of function that makes it the appropriate tool in many cases. As an example, a few of the many tasks provided by the current version of Ant, V1.6.2, include the ability to manipulate file contents, execute command-line and Java programs, and initiate SSH and FTP connections.

Because Ant buildfiles, which define all of the build logic, are written in XML, there is no code to recompile if the logic needs to change, and no language-specific syntax to understand. In addition, Ant is highly extensible. It provides the ability to create your own custom tasks using Java™ which can then be used the same way as any other Ant tasks. All of this taken together means Ant can be an excellent choice for carrying out many tasks.

In most cases, once buildfiles have been created, they are executed either by calling the Ant executable from the command line with the appropriate target (for example, ant dist) or using the WebSphere® Studio Application Developer (Application Developer) built-in Run Ant command. There may be times, however, when it is more appropriate to launch Ant from within a Java program. This may be to kick off a sequence of actions based on some set of conditions your Java program detects, or it may be just to take advantage of Ant's rich set of built-in function from within your program. In this case, you would go ahead and create a buildfile just as you would when invoking Ant from the command line, but you would then insert the correct calls to the Ant Java APIs into your program. This article will help you handle this process by examining the necessary Java code and showing you how to run this code within Application Developer.

This article does not cover invoking Ant tasks from Java without using a buildfile. For more information on that process, see Using Ant Tasks Outside of Ant in the Apache Ant user manual.


Invoking Ant Programmatically

The examples in this article make use of WebSphere Studio Application Developer 5.1.2. They may work with other versions, but this has not been tested. You can download a free trial version.

Creating the Ant buildfile from within Application Developer

We will briefly review the creation of buildfiles and other Ant basics in this article, but not cover them in detail. Please see the Related content and Resources sections for more information.

First, create a new Java project. Select File => New => Project, then select Java => Java Project and click on Next. Enter antSample for your project name and then click Finish. If asked about switching to the Java perspective, click Yes.


Figure 1: Creating a new Java project
Figure 1: Creating a new Java project in Application Developer

Now create a simple Ant buildfile so that you have something to test invoking. An Ant buildfile is just an xml file, so right-click on the antSample project, and choose New => Other... Then choose XML => XML and click on Next. Choose Create an XML file from scratch and then click on Next. Name your file build.xml and click Finish.


Figure 2: The package explorer after the buildfile has been created
Figure 2: The package explorer after the buildfile has been created

Copy the following into your xml file to create a simple buildfile.

<project name="testproject" default="test" basedir=".">
	<target name="test">
		<echo message="Hello World" />
	</target>
</project>

Save your file. To verify that it is a valid buildfile, run it using Application Developer's built-in Ant. Right-click on your build.xml file in the Package Explorer and choose Run Ant... The target "test" should already be checked to run since it is the default target so click Run. You should see output similar to this in your console:

Buildfile: C:\tempWorkspace\antSample\build.xml

test:
        [echo] Hello World
BUILD SUCCESSFUL
Total time: 4 seconds

Creating a class to invoke Ant

Now that you've verified that the buildfile is correct, you will need to create a Java class that you can use to invoke it via the Ant Java APIs. Right-click on the antSample project and choose New => Class. Enter AntSample as the name of the class and check the box next to public static void main(String[] args) under the question Which method stubs would you like to create? Click Finish and the AntSample class will be created for you along with its main method.

Because you will be using Ant APIs the next thing you need to do is add the jar files Ant needs to your classpath. Right-click on the antSample project and choose Properties from the menu. Click on Java Build Path, choose the Libraries tab, and choose Add External Jars.... Locate the folder where you installed WebSphere Studio and then navigate to eclipse => plugins => org.apache.ant_1.5.3. Choose ant.jar and click Open. Choose Add External Jars again and then navigate to eclipse => plugins => org.apache.xerces_4.0.13.

Choose xerces.jar and xmlParserAPIs.jar and then click Open again. Your build path should now look similar to:


Figure 3: The new Java build path
Figure 3: The new Java build path

Click OK on the Properties dialog to return to your AntSample class. Add the following code to the main method of AntSample:

File buildFile = new File("build.xml");
Project p = new Project();
p.setUserProperty("ant.file", buildFile.getAbsolutePath());
p.init();
ProjectHelper helper = ProjectHelper.getProjectHelper();
p.addReference("ant.projectHelper", helper);
helper.parse(p, buildFile);
p.executeTarget(p.getDefaultTarget());

Right-click anywhere within the file and choose Source => Organize Imports. This should clear any errors. Save the file.

Run the code by highlighting AntSample.java in the package explorer and then going to Run => Run As => Java Application. If you switch to the console, you'll see that the program runs and exits without any errors, but it doesn't produce any output.

In order to figure out why, let's examine the code to see what it is doing. First, it creates a file object from the build file and then creates a new Project object. Project is the Java class that Ant uses to represent an Ant project with all of its targets, tasks, and properties. It sets a property so that the project knows where the buildfile is located. It initializes that project, which causes the project to do some internal setup. Then it locates the default ProjectHelper, and uses that to parse the buildfile and populate the project with information from the buildfile. Next it executes the default target of the project.

You could also execute any target in the buildfile (in this buildfile there happens to be only one), by passing in the name of the target, for example, p.executeTarget("test"). Even though all of this happened successfully, you didn't see any output because Ant didn't know where the output should go. When Ant is executed from the command line or through Application Developer, the output automatically goes to the console. But here you need to be explicit. You need to add a BuildLogger and add it as a listener so it will receive notification of events that happen during the build.

Loggers

There are several different BuildLoggers you can use including DefaultLogger, AnsiColorLogger, MailLogger, and NoBannerLogger. Or you could write your own and register it with the project. In fact, you can register any class that implements the BuildListener interface to receive build events and react to them within your class (for example, receive a taskCompleted event and increment a progress bar). For this case, register the simplest logger, the DefaultLogger, and direct output messages to standard out and error messages to standard error. To do this, add the following lines of code after creating the project but before initializing the project:

DefaultLogger consoleLogger = new DefaultLogger();
consoleLogger.setErrorPrintStream(System.err);
consoleLogger.setOutputPrintStream(System.out);
consoleLogger.setMessageOutputLevel(Project.MSG_INFO);
p.addBuildListener(consoleLogger);

The message output level is configurable to several different levels. Right-click anywhere in the class file and choose Source => Organize Imports and then save. Now run the program again by going to the Run menu and choosing Run Last Launched. You'll see that you are now getting some output, but it is not exactly the same as the output you were getting before. Now you should see in the console:

test:
     [echo] Hello World

Build Events

So now you are getting the output, but you aren't getting any information about whether or not the build was successful or not, or the running time of the build. It turns out you also need to fire some events to let Ant know that the build is starting and that it has finished. You also need to include any exception that was thrown by the execute() method in the fireBuildFinished method so that it gets passed to the listener. After adding this code, the main method looks like this:

File buildFile = new File("build.xml");
Project p = new Project();
p.setUserProperty("ant.file", buildFile.getAbsolutePath());		
DefaultLogger consoleLogger = new DefaultLogger();
consoleLogger.setErrorPrintStream(System.err);
consoleLogger.setOutputPrintStream(System.out);
consoleLogger.setMessageOutputLevel(Project.MSG_INFO);
p.addBuildListener(consoleLogger);

try {
	p.fireBuildStarted();
	p.init();
	ProjectHelper helper = ProjectHelper.getProjectHelper();
	p.addReference("ant.projectHelper", helper);
	helper.parse(p, buildFile);
	p.executeTarget(p.getDefaultTarget());
	p.fireBuildFinished(null);
} catch (BuildException e) {
	p.fireBuildFinished(e);
}

Right-click anywhere in the class file and choose Source => Organize Imports and then save. Now when you run the code you should see the output you expect. To change the amount of information in the output, change the message output level (try Project.MSG_VERBOSE instead).

Older versions of Ant

The code in this article works for versions of Apache Ant 1.5 and higher. If you need to work with older versions of Ant, there are some changes you should make. First, instead of this code:

ProjectHelper helper = 
  ProjectHelper.getProjectHelper();
helper.parse(p, buildFile);



You will need to use the (now deprecated) code to accomplish the same thing:

Project.configureProject(p, buildFile);

Second, in Ant 1.4, the methods to fire events were protected. If you only need to work with 1.4 or earlier, you can just leave these out. But if you need to work with versions from 1.4 to 1.6+, you'll need to extend the Project class to make these methods public and then use your own Project class instead.

Properties

Just like in any other Ant buildfile you can define properties or import properties files into the buildfile. But there may be cases where you want to supply the properties programmatically, or override the values in the buildfile. Edit the build.xml file and replace Hello World with Hello ${name}. This is the syntax that tells Ant to perform variable substitution at runtime. Save the file.

If you run your program again (Run => Run Last Launched), you'll see that it outputs "Hello ${name}" because the value of the variable "name" hasn't been set yet. In AntSample.java, immediately below where you created the Project object, add the line:

p.setProperty("name", "Bob");

Save the file. Now run AntSample again (Run => Run Last Launched). You should now see output similar to:

test:
     [echo] Hello Bob

BUILD SUCCESSFUL
Total time: 1 second

You can even add the line <property name="name" value="Sally" /> to your build.xml file before the echo task, but it won't make any difference. The properties set programmatically will always override those set in the buildfile.


Conclusion

Now that you have the basics, the best way to learn more is to get your hands on the Ant javadoc in order to expand what you've done. Unfortunately, the Ant javadoc is not available as part of Application Developer, and is not available for browsing online at the Apache Ant Web site. This is to make sure that you are looking at javadocs that match your version of Ant. In order to obtain the javadocs, you will need to download Apache Ant V1.5.3 (the version that comes with Application Developer V5.1.2) from: http://archive.apache.org/dist/ant/binaries/. The javadocs are then in ANT_HOME\docs\manual\api. If you wish to use a newer version of Ant than the one that comes with Application Developer 5.1.2, search in the Application Developer help for "Upgrading Ant" or "Using a Different Version of Ant."


Resources

About the author

Nell Gawor

Nell Gawor is an advisory software engineer for IBM in Research Triangle Park, North Carolina, in the Software Group Advanced Design and Technology Group. She received a Masters Degree in Computer Science from the University of Illinois at Urbana-Champaign. Contact Nell at ngawor@us.ibm.com.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere, Java technology
ArticleID=35115
ArticleTitle=Invoking Apache Ant programmatically
publish-date=02092005
author1-email=ngawor@us.ibm.com
author1-email-cc=ngawor@us.ibm.com

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Try IBM PureSystems. No charge.

Special offers