How to develop a Task for Ant
public class HelloWorld {
public void execute() {
System.out.println("Hello World");
}
}
This class is wrapped by Ant's TaskAdapter and uses reflection for:
The class may extend Task or another class that was designed to be extended.
Class | Description |
---|---|
AbstractCvsTask | Another task can extend this with some customized output processing |
JDBCTask | Handles JDBC configuration needed by SQL type tasks. |
MatchingTask | This is an abstract task that should be used by all those tasks that require to include or exclude files based on pattern matching. |
Pack | Abstract Base class for pack tasks. |
Unpack | Abstract Base class for unpack tasks. |
DispatchTask | Abstract Base class for tasks that may have multiple actions. |
To define an attribute, a public setter method must be provided such as:
public void set<attributename>(<type> newValue)
and Ant will do the rest via reflection.
The name of the method must:
Ant supports any of these datatypes as arguments of the set-method:
Before calling the set-method all properties are resolved. So a ${msg} would not set the string to “${msg}” if there is a property “msg” with a set value.
Depending on the setter datatype argument, Ant will perform some DataType Conversions logic
The Project object gives some abilities:
The Project object is:
Hello World with the use of the project class
package ant.mytask;
import org.apache.tools.ant.Project;
public class HelloWorld {
private Project project;
public void setProject(Project proj) {
project = proj;
}
public void execute() {
String message = project.getProperty("ant.project.name");
project.log("Here is project '" + message + "'.", Project.MSG_INFO);
}
}
Two useful methods from class Project:
If the task shall contain other tasks as nested elements (like parallel), your class must implement the interface TaskContainer. If you do so, your task can not support any other nested elements.
Execution Ant will call the perform method in Task, which in turn calls execute. This method makes sure that Build Events will be triggered. If you execute the task instances nested into your task, you should also invoke perform on these instances instead of execute.
A class must be create that will represent a nested element. Example: FileSet support nested fileset elements.
Attributes of the nested elements or nested child elements of them are handled using the same mechanism used for bar tasks. i.e.:
To support nested element, the class need to add one of the below method:
Example with an <inner> nested element:
public NestedElement createInner()
The add (or addConfigured) method must be:
The Nested element class must have:
Example with an <inner> nested element:
public void addInner(NestedElement anInner)
public void addConfiguredInner(NestedElement anInner)
When a task wants to prompt a user for input. See InputHandler
To use a task directly from the buildfile which created it, place the <taskdef> declaration inside a target after the compilation. Use the classpath attribute of <taskdef> to point to where the code has just been compiled.
<?xml version="1.0"?>
<project name="OwnTaskExample2" default="main" basedir=".">
<!-- Compilation -->
<target name="build" >
<mkdir dir="build"/>
<javac srcdir="source" destdir="build"/>
</target>
<!-- Declare the task after compilation -->
<target name="declare" depends="build">
<taskdef name="mytask"
classname="com.mydomain.MyVeryOwnTask"
classpath="build"/>
</target>
<!-- Use the task after declaration -->
<target name="main" depends="declare">
<mytask message="Hello World! MyVeryOwnTask works!"/>
</target>
</project>
To add the task more permanently, you can add to the default.properties file in the org.apache.tools.ant.taskdefs package: