Table of contents
Apache Ant
Ant file locations
linux location for ant dependencies (all users)
/usr/share/ant/lib/
location for ant dependencies (current user)
[HOME]/.ant/lib/
Command line
invoke default target on build.xml
ant
verbose mode
ant -v
invoke specified target on build.xml
ant [target]
invoke a target on a sepecified build file
ant [target] -f [build_file]
set the [name] property to [value]
ant [target] -D[name]=[value]
supply an ant dependency (e.g. ant-junit.jar)
ant -lib [ant]
hello world
<project default="hello">
<target name="hello">
<echo>hello</echo>
</target>
</project>
increase logging verbosity
<script language="javascript">
var logger = project.getBuildListeners( ).firstElement( );
logger.setMessageOutputLevel( 9 );
</script>
Paths
printing a path
<pathconvert property="[property]" refid="[id]"/>
<echo>${[property]}</echo>
passing a path to another ant target (for example, to reuse the compile target)
<ant antfile="${[file]}" target="[target]">
<property name="compile.path" value="${toString:test.compile.path}" />
</ant>
Properties
detect windows
<condition property="os.windows">
<os family="windows" />
</condition>
configuring a target with all properties in a file
<ant antfile="${[file]}" target="[target]">
<property file="${file}" />
</ant>
macro for regex replace in property
<macrodef name="regexreplace">
<attribute name="property" />
<attribute name="in" />
<attribute name="replace" />
<attribute name="with" />
<sequential>
<loadresource property="@{property}">
<propertyresource name="@{in}" />
<filterchain>
<replaceregex pattern="@{replace}" replace="@{with}" flags="g" />
</filterchain>
</loadresource>
</sequential>
</macrodef>
input output
downloading a file (wget)
<get src="${url}" dest="${destination}" />
downloading a file only if missing
<get src="${url}" dest="${destination}" skipexisting="true" />
javadoc
javadoc simple
<javadoc sourcepath="${src}" destdir="${api}" defaultexcludes="yes" version="true" use="true" />
Checks
checking that a directory exists
<available file="${dir}" type="dir" property="myproperty"/>
checking that a particular port is taken / available
<condition property="webserver.online">
<socket server="localhost" port="${webserver.port}"/>
</condition>
<fail if="webserver.online" message="port ${webserver.port} already taken! Is the webserver already running?" />
packing
create zip file (overwrites any existing zip)
<zip destfile="file.zip" basedir="sources" />
create or update zip file
<zip destfile="file.zip" basedir="sources" update="true" />
merging zip files
<zip destfile="merged.zip">
<zipgroupfileset dir="zips" includes="*.zip"/>
</zip>
merge libs into a jar we are creating
<jar destfile="${jar}">
<fileset dir="${build.main.classes.dir}" />
<zipgroupfileset dir="${project.lib.compile.dir}" includes="*.jar"/>
</jar>
SQL
running a select query on a database
<project default="mysql">
<property name="db.jar" value="mysql-connector-java-8.0.22.jar" />
<property name="db.driver" value="com.mysql.cj.jdbc.Driver" />
<property name="db.host" value="localhost" />
<property name="db.database" value="mysql" />
<property name="db.user" value="root" />
<property name="db.password" value="secret" />
<property name="db.url" value="jdbc:mysql://${db.host}/${db.database}" />
<target name="mysql">
<sql driver="${db.driver}" url="${db.url}" userid="${db.user}" password="${db.password}" print="true">
<classpath>
<pathelement location="${db.jar}"/>
</classpath>
show tables;
</sql>
</target>
</project>
ant macros
macro with attribute
<macrodef name="hello-world">
<attribute name="message"/>
<sequential>
<echo message="@{message}" />
</sequential>
</macrodef>
invoking the above macro
<hello-world message="Foo! Bar!" />
attribute with default
<macrodef name="hello-world">
<attribute name="message" default="I have nothing to say"/>
<sequential>
<echo message="@{message}" />
</sequential>
</macrodef>
invoking the above macro
<hello-world />
macro with element
<macrodef name="identity">
<element name="body"/>
<sequential>
<body/>
</sequential>
</macrodef>
invoking the above macro
<identity>
<body>
<echo>Foo! Bar!</echo>
</body>
</identity>
macro for asserting file exists
<macrodef name="require">
<attribute name="file"/>
<attribute name="message" default="Error! file does not exist: @{file}"/>
<sequential>
<fail message="@{message}">
<condition>
<not>
<available file="@{file}" />
</not>
</condition>
</fail>
</sequential>
</macrodef>
use like this
<require file="${file}"/>
<require file="${file}" message="optional custom message"/>
Further reading
https://ant.apache.org/manual/Tasks/macrodef.html
ant scripting
hello world
<script language="javascript">
java.lang.System.out.println("hello javascript!");
</script>
escape angular brackets
<script language="javascript">
<![CDATA[
java.lang.System.out.println("<hello>");
]]>
</script>
invoke a task
<script language="javascript">
var echo = project.createTask("echo");
echo.setMessage("hello from echo task");
echo.perform();
</script>
read a property
<property name="property.key" value="hello xml property"/>
<script language="javascript">
java.lang.System.out.println(project.getProperty('property.key'));
</script>
set a property
<script language="javascript">
project.setProperty('property.key', 'hello javascript property');
</script>
<echo>${property.key}</echo>
iterate the elements of a directory
<property name="property.containing.dir" value="/tmp"/>
<script language="javascript">
<![CDATA[
var path = project.getProperty('property.containing.dir');
var dir = new java.io.File(path);
var children = dir.listFiles();
for(i=0; i<children.length; i++) {
var child = children[i];
if(child.isDirectory()) {
java.lang.System.out.println(child);
}
}
]]>
</script>
documentation
https://ant.apache.org/manual