Monday, January 19, 2009

Using Ant as a library

Ant has a lot of predefined tasks that could be a great help. You can use them directly from your Java code. Here are some examples using Ant to download a file, unzip a package and exec some shell command.

You would need to have
+ ant-1.7.1.jar
+ ant-launcher-1.7.1.jar
+ commons-io-1.3.2.jar (for exec example, found at http://commons.apache.org/io)

in your classpath.


public class AntDemo {

/**
* Download a file at sourceUrl to dest
*
*/
public static void download(URL sourceUrl, File dest) {
Project dummyProject = new Project();
dummyProject.init();

Get antGet = new Get();
antGet.setProject(dummyProject);
antGet.setVerbose(true);
antGet.setSrc(sourceUrl);
antGet.setDest(dest);
antGet.execute();
}

/**
* Unzip a zip file
*
*/
public static void unzip(File src, File dest) {
Project dummyProject = new Project();
dummyProject.init();

Expand antUnzip = new Expand();
antUnzip.setProject(dummyProject);
antUnzip.setSrc(src);
antUnzip.setDest(dest);
antUnzip.execute();

/* ant doesn't preserve permission bits
need to restore them manually */

Chmod chmod = new Chmod();
chmod.setProject(dummyProject);
chmod.setDir(new File(src.getAbsolutePath().replaceAll(".zip", "")));
chmod.setPerm("a+rx");
chmod.setIncludes("**/**");
chmod.execute();
}


/**
* Run a shell command and return the output as String
*
*/
public static String exec(String command, List params, File workDir) {
File outputFile;
try {
outputFile = File.createTempFile("exec", ".out");
} catch (IOException e) {
throw new RuntimeException(e);
}

Project dummyProject = new Project();
dummyProject.init();

ExecTask execTask = new ExecTask();
execTask.setProject(dummyProject);
execTask.setOutput(outputFile);
execTask.setDir(workDir != null ? workDir : new File(System
.getProperty("user.dir")));
execTask.setExecutable(command);
if (params != null) {
for (String param : params) {
execTask.createArg().setValue(param);
}
}

execTask.execute();

FileReader reader = null;
try {
reader = new FileReader(outputFile);
return IOUtils.toString(reader);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
IOUtils.closeQuietly(reader);
outputFile.delete();
}
}

public static void main(String[] args) {
List params = Arrays.asList(new String[] { "Hello", "World" });
System.out.println(exec("echo", params, null));
}
}


Just note that you'll need a dummy project for the Ant task. Otherwise you'll get an NullPointerException.

There are a lot of tasks that you could use. The list is here http://ant.apache.org/manual/tasksoverview.html

4 comments:

Anonymous said...

You don't need commons-io if you use org.apache.tools.ant.util.FileUtil's readFully and close methods which you get for free by having Ant around.

Unknown said...

Thanks bodewig for a nice tip.

bendigi said...

This is great help. I am loving it.

Question:
Can we call an actual ant file using the "Project" ?

I will follow your example for the junitTask and junitReport, unless there is a better way to call Junits from within java.

Unknown said...

I took a look at their API and SubAnt might be your best bet. It's just a regular ant task and you can specify the path to your external ant file through SubAnt.setAntfile()

For junit stuff, you might as well experiment and see how it works out for you.