Software requirements

In order to use Antifact, you need ant 1.6.2.


Antifact is a project dependency augmentation for ant. It gravitates around the artifact notion, which is nothing more than a FileSet in ant terminology. It can be easily integrated with existing ant projects and promotes beautiful ideas like continuous integration, modularity, world peace and so on.

A project declares the artifacts it exports and how they can be built. Other projects can import these artifacts and use them.

For example, a logging library project will export a jar file with the logging classes as one of it's artifacts. Other projects, which need logging services, will import the jar artifact use it.

A project can export multiple artifacts. If we continue with the previously mentioned logging library project, one of its artifacts will be the jar file, another artifact probably a zip file containing the javadoc documentation etc.

Declaring artifacts is really easy. It's done in a XML file (practically an ant file), which is called artifacts.xml in our example. Here is the content of this file for the logging library project:

<project name="uncommons-logging-artifacts">
    <artifact antfile="build.xml" targets="jar" clean="clean" name="jar.files">
        <fileset dir="build/lib" includes="uncommons-logging.jar"/>

    <artifact antfile="build.xml" targets="javadoc, zip-javadoc" clean="clean" name="javadoc.files">
        <fileset dir="build/javadoc" includes="uncommons-logging-docs.zip"/>

There are two artifacts declared in artifacts.xml: one is called jar.files and contains uncommons-logging.jar from the build/lib directory; the other one is called javadoc.files and contains uncommons-logging-docs.zip from build/javadoc. As you can see, the jar.files artifact is built by invoking the jar target from build.xml, and cleaned by clean. javadoc.files is built by invoking two targets from the same build.xml ant file: first javadoc, then zip-javadoc. clean is used to delete the artifact. Pretty simple, heh?

Now let's use uncommons-logging's exported artifacts. There are two steps which must be done: the artifact must be imported, and then it must be built. The artifactimport tasks is used to import the artifact. It is a top-level task which must be placed outside of any target in the ant file which imports the artifact.

<artifactimport file="artifacts.xml" name="jar.files" localids="uncommons-logging.jar.files"/>

The line above imports the artifact jar.files declared inside artifacts.xml, and gives it a local id (under which it can be referenced) uncommons-logging.jar.files. To import more artifacts from the same build file, following construct should be used:

<artifactimport file="artifacts.xml">
    <artifactmapper name="jar.files" localids="uncommons-logging.jar.files"/>
    <artifactmapper name="javadoc.files" localids="uncommons-logging.doc.files"/>

To effectively use the artifact, it must be built. Here's a compilation example which uses uncommons-logging.jar in it's classpath:

<target name="compile" depends="build-artifact">
    <javac destdir="...." srcdir="src">
            <fileset refid="uncommons-logging.jar.files"/>
<target name="build-artifact">
    <artifactbuild localids="uncommons-logging.jar.files"/>

As you can see, before compiling our application which uses the very uncommon logging, the uncommons-logging library is built. This happens in the build-artifact target. The artifact and the FileSet which defines its contents are referenced by the local id specified on import.

Not all artifacts must be built. One can declare an artifact containing a static FileSet, which is not a result of a build process. For example, documentation is often written, and not generated.

<project name="uncommons-logging-artifacts">
    <artifact name="jar.files" .....
    <artifact name="tutorial.files">
        <fileset dir="src/docs/tutorial" includes="**/*"/>

An artifact can depend on another artifact, and so on. Antifact will take care of calling the artifact-building targets in the right order. For example if A1 depends on A2 and A3, A2 and A3 depend on A4 the build order will be A4, A2, A3, A1. Take note that building of A4 isn't invoked twice, although both A2 and A3 depend on it. There's more documentation about dependencies under ....

Don't forget to take a look at the rest of the documentation and the examples. Enjoy.

Related projects

There is a similar project going on (from which, to be fair, i took some nice ideas): antlion