Apache Ant logo

Apache Ant should be familiar to every Java programmer. It is a popular software build tool, completely written in Java. Ant uses a build script, which is a simple XML file. Web developers also use this tool even though it's Java-oriented.

5 steps to start Ant:

  1. Installation and check.
  2. Write a simple HelloWorld script.
  3. Specify the project name and the default target.
  4. Find the minimum required list of tasks.
  5. Build and test Java projects.

1. Installation and check

Before installation, we need the following prerequisites:

  • Download the Java SE Development Kit, JDK. 
  • Your favorite text editor:  vi/vim/gedit in Linux or Windows Notepad++
  • Basic skills in the command line. Build scripts and Java examples have been tested in Linux (Simply Linux 7.95.0, CentOS Linux 6.8) and Windows (XP/7). Using Ant is the same for both Linux and Windows.

Ant can easily be installed from the repository using a command like sudo apt-get install ant (replace apt-get on yum if necessary). Important: we need a version no lower than 1.8.*. We have version 1.7.1 in the CentOS 6.8 repository, so it's better to use this script, which is offered in the previous article.

We check the operability by calling ant in the command line:

$ ant -version
Apache Ant(TM) version 1.10.1 compiled on February 2 2017

If we see a similar message – everything is OK.

2. Write a HelloWorld script

<?xml version="1.0"?>
<project name="HelloWorld" default="hello">
    <target name="hello">
        <echo>Hello, World!</echo>
    </target>
</project>

We create the hello subdirectory in the home directory. To do this in Linux, use the mkdir command. Then save the file containing this script with the name build.xml. We go to this directory by calling ant:

$ mkdir hello
$ cd hello

$ ant

Buildfile: /home/lamp/hello/build.xml

hello:
[echo] Hello, World!
BUILD SUCCESSFULL

Total time: 0 seconds

What happens? Ant finds the script file with the default name (build.xml) and executes the target with the name hello also specified by default in the project tag using the default attribute (note that in the project tag we also specify the name of the project using the name attribute). We get the same result if we call ant with the hello parameter:

$ ant hello

3. Specify the project name and the default target

It is essential to understand the basic principles of work and the XML format of the build script. The build script is a simple XML file. The text is opened (and closed) by the project tag in which you can specify the project name and the default target. It also contains a definition of goals (target), dependencies (depends), and properties (property). The simplest script should have at least one target. In the target tag, we describe the call of one or more tasks. You can specify a name using the name attribute (name="name_of_target") for the target. The given name becomes a command for our script and you can call the corresponding target in the following way:

$ ant name_of_target

The target also has the ability to specify a dependency using the depends attribute. Dependencies link the targets with each other. For example, there is a target named "compile", and another one with the name "run", dependent on "compile". And if we want to run "run", "compile" will be executed first.

4. Find the minimum required list of tasks

The standard version of Ant contains more than 150 tasks. We need only these seven tasks:

  • echo – outputs messages to the console
  • mkdir – creates directories
  • delete – delete files and directories
  • javac – compiles Java code
  • java – launching class and jar files
  • jar – creates a jar file
  • junit – runs tests

5. Build and test Java projects

In the next steps, we will write a script for a full cycle of building and testing a training project. Ant provides complete freedom in the formation of a directory structure. We create in our hello directory a subdirectory src for the source code in Java:

$ mkdir src

Save a file named HelloWorld.java with the following content:

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

Now let's slightly complicate our script (build.xml):

<?xml version="1.0"?>
<project name="HelloWorld" default="run">
    <target name="compile" depends="mkdir">
        <mkdir dir="build/classes"/>
        <javac destdir="build/classes" includeantruntime="false">
            <src path="src"/>
        </javac>
    </target>
    <target name="run" depends="compile">
        <java classname="HelloWorld" classpath="build/classes"/>
    </target>
    <target name="clean">
        <delete dir="build"/>
    </target>
</project>

As a result, the script has three targets (commands): compile (compiling the .java file(s)), run (starting the .class file), clean (deleting the folders with the results of the compilation). In this case, compile contains two tasks – mkdir and javac. Note the dependency: target run will call compile beforehand. In addition, run is the default target for the project.

Run the script without parameters and see the result of working the Java program: Hello, World!

The direct indication of directory names doesn't imply a good style, especially if the directory names in the script are repeated. We modify build.xml using property (note how the project name is used in the script below) and add a couple of comments:

<?xml version="1.0"?>
 <project name="HelloWorld" default="run">
     <!-- define names of directories -->
     <property name="src" location="src"/>
     <property name="build" location="build"/>
     <property name="classes" location="${build}/classes"/>
     <!-- define all targets -->
     <target name="compile">
         <mkdir dir="${classes}"/>
         <javac srcdir="${src}" destdir="${classes}" includeAntRuntime="false"/>
     </target>
     <target name="run" depends="compile">
         <java classname="${ant.project.name}" classpath="${classes}"/>
     </target>
     <target name="clean">
         <delete dir="${build}"/>
     </target>
 </project>

Now add the target package to generate the jar file:

<target name="package" depends="compile">
    <jar destfile="${build}/${ant.project.name}.jar" basedir="${classes}">
        <manifest>
            <attribute name="Main–Class" value="${ant.project.name}"/>
        </manifest>
    </jar>
</target>

Make sure everything works:

$ ant package
$ java -jar build/HelloWorld.jar
Hello, World!

Let's start testing. We change the project code (to have something for testing):

public class HelloWorld {
    public static void main(String[] args) {
        HelloWorld hello = new HelloWorld();
        System.out.println(hello.sayHello());
    }
    String sayHello() {
        return "Hello, World!";
    }
}

Add the file/class TestHello.java (containing a simple test) to the src directory:

import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class TestHello {
    @Test
    public void testHello() {
        HelloWorld hello = new HelloWorld();
        assertEquals("Hello, World!", hello.sayHello());
    }
}

Next, download two files, junit-4.12.jar and hamcrest-core-1.3.jar from the GitHub page. Then copy them to the directory of our JDK/jre/lib/ext.

I use this copy command in CentOS 6.8:

$ sudo cp ~/Downloads/*.jar /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.121-0.b13.el6_8.i386/jre/lib/ext/

Now, we can check the test in the command line:

$ java -cp build/classes org.junit.runner.JUnitCore TestHello

JUnit version 4.12
.
Time: 0,281
OK (1 test)

Add one more target with the name test to our script:

<target name="test" depends="compile">
    <junit>
        <classpath>
            <pathelement location="${classes}"/>
        </classpath>
        <test name="TestHello"/>
    </junit>
</target>

Complete the line in the package target (jar):

<jar destfile="${build}/${ant.project.name}.jar" basedir="${classes}" excludes="Test*.class">

Now, test is added to the list of commands in our script (besides compile, run, package, clean).

After this, we change the code of our project so that the greeting is displayed in a separate graphical window.

Then we create a jar file and run it with a double mouse click since you should be configured to execute jar files by double-clicking.

The third version of Java code:

import javax.swing.*;
import java.awt.*;
public class HelloWorld extends JFrame {
    public static void main(String[] args) {
        new HelloWorld();
    }
    HelloWorld() {
        setTitle(sayHello());
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setBounds(200, 200, 300, 200);
        JLabel label = new JLabel(sayHello(), SwingConstants.CENTER);
        label.setFont(new Font("", Font.BOLD, 24));
        add(label);
        setVisible(true);
    }
    String sayHello() {
        return "Hello, World!";
    }
}

We change the script a little (in the run target), adding fork="true" (execution of the class in another virtual machine). Otherwise, the run will not work (having been checked experimentally):

<java classname="${ant.project.name}" classpath="${classes}" fork="true"/>

We execute the command to generate the jar file ($ ant package), open the ~/hello/build directory in the file explorer, find HelloWorld.jar, double click on it and enjoy viewing the graphical window with the greeting.

Summary

We hope this was a quick and easy demo. Learn more about Red Hat Development Suite, a fully integrated development environment for modern enterprise development. Play in our Sandbox to get more practice.

Last updated: March 20, 2023