Last modified: Nov 20, 2013
YAAP[1], Ivy adds the dependency management features pioneered by Maven to ant
Technically can run as a standalone application, but really the ant integration is key.
Use is similar to the dependencies/repositories portion of Maven POMs
Ivy can retrieve from and publish to the established Maven repositories
Ivy Motivation and Features
“Apache Ivy brings the dependency management advantages of Apache Maven to Apache Ant build files, for those who already use Apache Ant and don’t want to migrate to Apache Maven.”
(source)
HTML & graphic reports
Easily added: a few ant tasks will fetch Ivy and integrate it into the build
Start with an Ant Project
Again, let’s start with the Code Annotation project.
<project name="codeAnnotation" basedir="." default="build">
<record name="ant.log" action="start" append="false" />
<taskdef classpath="JFlex.jar" classname="JFlex.anttask.JFlexTask" name="jflex" /> ➊
<echo>loading build-${os.name}.paths</echo>
<include file="build-${os.name}.paths"/> ➋
<target name="generateSource">
<mkdir dir="src/main/java"/>
<jflex file="src/main/jflex/code2html.flex"
destdir="src/main/java"/>
<jflex file="src/main/jflex/code2tex.flex"
destdir="src/main/java"/>
<jflex file="src/main/jflex/list2html.flex"
destdir="src/main/java"/>
<jflex file="src/main/jflex/list2tex.flex"
destdir="src/main/java"/>
</target>
<target name="compile" depends="generateSource">
<mkdir dir="target/classes"/>
<javac srcdir="src/main/java" destdir="target/classes"
source="1.7" includeantruntime="false"/>
</target>
<target name="compile-tests" depends="compile">
<mkdir dir="target/test-classes"/>
<javac srcdir="src/test/java" destdir="target/test-classes"
source="1.7" includeantruntime="false">
<classpath refid="testCompilationPath"/>
</javac>
</target>
<target name="test" depends="compile-tests">
<property name="mypath" refid="testExecutionPath"/>
<echo>testExecutioPath is ${mypath}</echo>
<echoproperties/>
<mkdir dir="target/test-results/details"/>
<junit printsummary="yes"
haltonfailure="yes" fork="no"
>
<classpath refid="testExecutionPath"/>
<formatter type="xml"/>
<batchtest todir="target/test-results/details">
<fileset dir="target/test-classes">
<include name="**/*Test*.class"/>
</fileset>
</batchtest>
</junit>
<junitreport todir="target/test-results">
<fileset dir="target/test-results/details">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames" todir="target/test-results/html"/>
</junitreport>
</target>
<target name="build" depends="test">
<jar destfile="codeAnnotation.jar" basedir="target/classes">
<manifest>
<attribute name="Main-Class"
value="edu.odu.cs.code2html.Code2HTML"/>
</manifest>
</jar>
</target>
<target name="clean">
<delete dir="target"/>
</target>
</project>
➊ This depends on JFlex.jar sitting in the project root directory
<project>
<path id="testCompilationPath">
<pathelement location="/usr/share/java/junit4.jar"/>
<pathelement path="target/classes"/>
</path>
<path id="testExecutionPath">
<pathelement location="/usr/share/java/junit4.jar"/>
<pathelement path="target/classes"/>
<pathelement path="target/test-classes"/>
</path>
</project>
Fetching Ivy
Start by having our build file actually load Ivy
<project name="codeAnnotation" basedir="." default="build"
xmlns:ivy="antlib:org.apache.ivy.ant">
<record name="ant.log" action="start" append="false" />
<property name="ivy.install.version" value="2.3.0"/>
<property name="ivy.jar.dir" value="${basedir}/ivy"/>
<property name="ivy.jar.file" value="${ivy.jar.dir}/ivy.jar"/>
<target name="download-ivy" unless="skip.download">
<mkdir dir="${ivy.jar.dir}"/>
<echo message="installing ivy..."/>
<get src="http://repo1.maven.org/maven2/org/apache/ivy/ivy/${ivy.install.version}/ivy-${ivy.install.version}.jar"
dest="${ivy.jar.file}" skipexisting="true"/>
</target>
<target name="install-ivy" depends="download-ivy"
description="--> install ivy">
<path id="ivy.lib.path">
<fileset dir="${ivy.jar.dir}" includes="*.jar"/>
</path>
<taskdef resource="org/apache/ivy/ant/antlib.xml"
uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/>
</target>
⋮
<target name="generateSource">
⋮
</target>
<target name="compile" depends="generateSource">
⋮
</project>
The install-ivy target binds the ivy: namespace (from the root element) to a class in the downloaded Ivy jar.
Specifying our Desired Libraries
We list the libraries our project needs in a separate ivy.xml file
<ivy-module version="2.0">
<dependencies>
<dependency org="de.jflex" name="jflex" rev="1.4.3"/>
<dependency org="junit" name="junit" rev="4.10"/>
</dependencies>
</ivy-module>
This should look familiar to the section from the Maven pom:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
</dependencies>
Ivy is Often Simpler
Although the handling of Junit is similar, compare the handling of JFlex in Ivy:
<ivy-module version="2.0">
<dependencies>
<dependency org="de.jflex" name="jflex" rev="1.4.3"/>
<dependency org="junit" name="junit" rev="4.10"/>
</dependencies>
</ivy-module>
to Maven:
<build>
⋮
<pluginManagement>
<plugins>
<plugin>
<groupId>de.jflex</groupId>
<artifactId>maven-jflex-plugin</artifactId>
<version>1.4.3</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
Maven makes a distinction between simple library dependencies and plugins.
Invoking Ivy
Once Ivy is installed, we can invoke it:
<project name="codeAnnotation" basedir="." default="build"
xmlns:ivy="antlib:org.apache.ivy.ant">
⋮
<target name="resolve-ivy" depends="install-ivy">
<ivy:retrieve/> ➊
<echo>ivy.default.ivy.user.dir is ${ivy.default.ivy.user.dir}</echo>
<taskdef classpath="JFlex.jar"
classname="JFlex.anttask.JFlexTask" name="jflex" /> ➋
</target>
<target name="generateSource" depends="resolve-ivy"> ➍
<mkdir dir="target/gen/java"/>
<jflex file="src/main/jflex/code2html.flex" ➌
destdir="target/gen/java"/>
<jflex file="src/main/jflex/code2tex.flex"
destdir="target/gen/java"/>
⋮
Set Up Classpaths
… to use the newly downloaded libraries.
<project name="codeAnnotation" basedir="." default="build"
xmlns:ivy="antlib:org.apache.ivy.ant">
<record name="ant.log" action="start" append="false" />
<path id="testCompilationPath">
<fileset dir="lib" includes="*.jar"/>
<pathelement path="target/classes"/>
</path>
<path id="testExecutionPath">
<fileset dir="lib" includes="*.jar"/>
<pathelement path="target/classes"/>
<pathelement path="target/test-classes"/>
</path>
<property name="ivy.install.version" value="2.3.0"/>
<property name="ivy.jar.dir" value="${basedir}/ivy"/>
<property name="ivy.jar.file" value="${ivy.jar.dir}/ivy.jar"/>
<property name="build.dir" value="build"/>
<property name="src.dir" value="src"/>
<target name="download-ivy" unless="skip.download">
<mkdir dir="${ivy.jar.dir}"/>
<echo message="installing ivy..."/>
<get src="http://repo1.maven.org/maven2/org/apache/ivy/ivy/${ivy.install.version}/ivy-${ivy.install.version}.jar"
dest="${ivy.jar.file}" usetimestamp="true"/>
</target>
<target name="install-ivy" depends="download-ivy"
description="--> install ivy">
<path id="ivy.lib.path">
<fileset dir="${ivy.jar.dir}" includes="*.jar"/>
</path>
<taskdef resource="org/apache/ivy/ant/antlib.xml"
uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/>
</target>
<target name="resolve-ivy" depends="install-ivy">
<ivy:retrieve/>
<echo>ivy.default.ivy.user.dir is ${ivy.default.ivy.user.dir}</echo>
<taskdef classpath="JFlex.jar"
classname="JFlex.anttask.JFlexTask" name="jflex" />
</target>
<target name="generateSource" depends="resolve-ivy">
<mkdir dir="target/gen/java"/>
<jflex file="src/main/jflex/code2html.flex"
destdir="target/gen/java"/>
<jflex file="src/main/jflex/code2tex.flex"
destdir="target/gen/java"/>
<jflex file="src/main/jflex/list2html.flex"
destdir="target/gen/java"/>
<jflex file="src/main/jflex/list2tex.flex"
destdir="target/gen/java"/>
</target>
<target name="compile" depends="generateSource">
<mkdir dir="target/classes"/>
<javac srcdir="target/gen/java" destdir="target/classes"
source="1.6" includeantruntime="false"/>
<javac srcdir="src/main/java" destdir="target/classes"
source="1.6" includeantruntime="false"/>
</target>
<target name="compile-tests" depends="compile">
<mkdir dir="target/test-classes"/>
<javac srcdir="src/test/java" destdir="target/test-classes"
source="1.6" includeantruntime="false">
<classpath refid="testCompilationPath"/>
</javac>
</target>
<target name="test" depends="compile-tests">
<mkdir dir="target/test-results/details"/>
<junit printsummary="yes"
haltonfailure="yes" fork="no"
>
<classpath refid="testExecutionPath"/>
<formatter type="xml"/>
<batchtest todir="target/test-results/details">
<fileset dir="target/test-classes">
<include name="**/*Test*.class"/>
</fileset>
</batchtest>
</junit>
<junitreport todir="target/test-results">
<fileset dir="target/test-results/details">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames" todir="target/test-results/html"/>
</junitreport>
</target>
<target name="build" depends="test">
<jar destfile="codeAnnotation.jar" basedir="target/classes">
<manifest>
<attribute name="Main-Class"
value="edu.odu.cs.code2html.Code2HTML"/>
</manifest>
</jar>
<zip destfile="target/codeAnnotation-src.zip">
<fileset dir=".">
<include name="*.xml"/>
<include name="test.cpp"/>
<include name="*.css.cpp"/>
<include name="src/**/*"/>
<exclude name="**/*~"/>
<exclude name="target/**/*"/>
</fileset>
</zip>
</target>
<target name="clean">
<delete dir="target"/>
</target>
<target name="cleaner" depends="clean">
<delete dir="lib"/>
</target>
<target name="cleanest" depends="cleaner">
<delete dir="ivy"/>
</target>
</project>
Yet Another Apache Project ↩