Move from Ant to Maven via Ivy

Some months ago, I had a little step into Apache Ivy. At the moment, I’m working on a multiple-components legacy project that is based on Apache Ant with no Dependency-Management. While trying to push our devs into the great World of Apache Maven, I came up to the point that it won’t be possible in short time. But we need a management of complex dependencies, so I looked „back“ to Ivy and came up with the idea of getting only the required libs to a known location via Ivy. The rest will stay as it is and nothing would change. So here’s my little example:

|   build.xml
|
+---ivy
|       ivy-build.xml
|       ivy-dependencies.xml
|       ivy-settings.xml
|
\---src
    \---eu
        \---christophburmeister
            \---testapp
                    EchoTest.java
 
<project name="ivy-test" basedir="." default="package">

	<property name="project.name" value="${ant.project.name}" />
	<property name="src.dir" location="${basedir}/src" />
	<property name="target.dir" location="${basedir}/target" />
	<property name="classes.dir" location="${target.dir}/classes" />
	<property name="ivy.dir" location="${basedir}/ivy" />
	<property name="dependencies.dir" location="${target.dir}/dependencies" />
	<property name="ivy.version" value="2.3.0" />
	<property name="ivy.jar.file" value="${ivy.work.dir}/ivy-${ivy.version}.jar" />
	<property name="repo.host" value="localhost" />
	<property name="repo.realm" value="Artifactory Realm" />
	<property name="repo.username" value="admin" />
	<property name="repo.password" value="password" />

	<path id="classpath.dependencies">
		<fileset dir="${dependencies.dir}">
			<include name="*.jar" />
		</fileset>
	</path>

	<target name="clean">
		<delete dir="${target.dir}" />
	</target>

	<target name="prepare" depends="clean">
		<mkdir dir="${target.dir}" />
		<mkdir dir="${classes.dir}" />
	</target>

	<target name="get.dependencies" depends="prepare">
		<ant antfile="${basedir}/ivy/ivy-build.xml" target="ivy.retrieve.dependencies">
			<property name="ivy.work.dir" value="${target.dir}/ivy" />
			<property name="ivy.settings.file" value="${ivy.dir}/ivy-settings.xml" />
			<property name="ivy.dependency.file" value="${ivy.dir}/ivy-dependencies.xml" />
			<property name="ivy.dependencies.dir" value="${dependencies.dir}" />
		</ant>
	</target>

	<target name="compile" depends="get.dependencies">
		<javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath.dependencies" />
	</target>

	<target name="package" depends="compile">
		<jar destfile="${target.dir}/${project.name}.jar" basedir="${classes.dir}" />
	</target>

</project>
 
<project name="ivy-test" default="ivy.retrieve.dependencies" xmlns:ivy="antlib:org.apache.ivy.ant">
	
	<target name="clean">
		<delete dir="${ivy.work.dir}"/>
		<delete dir="${ivy.dependencies.dir}"/>
	</target>
	
	<target name="ivy.download" depends="clean">
		<mkdir dir="${ivy.work.dir}"/>
		<mkdir dir="${ivy.dependencies.dir}" />
		<get src="http://repo2.maven.org/maven2/org/apache/ivy/ivy/${ivy.version}/ivy-${ivy.version}.jar" 
             dest="${ivy.jar.file}" usetimestamp="true" verbose="true"/>
	</target>

	<!-- initiate the ivy-taskdefs -->
	<target name="ivy.init" depends="ivy.download">
		<echo message="looking for ivy-taskdefs in ${ivy.jar.file}" />
		<taskdef resource="org/apache/ivy/ant/antlib.xml" uri="antlib:org.apache.ivy.ant">
			<classpath>
				<pathelement location="${ivy.jar.file}"/>
			</classpath>
		</taskdef>
		<echo message="found ivy-taskdefs in ${ivy.jar.file}" />
	</target>


	<!-- get the dependencies from repository -->
	<target name="ivy.retrieve.dependencies" depends="ivy.init">
		<ivy:settings file="${ivy.settings.file}">
			<credentials host="${repo.host}" realm="${repo.realm}" username="${repo.username}" passwd="${repo.password}"/>
		</ivy:settings>
		<ivy:cleancache />
		<ivy:retrieve file="${ivy.dependency.file}" pattern="${ivy.dependencies.dir}/[artifact]-[revision].[ext]" transitive="true" />
	</target>

</project>
 
<ivysettings>
	<settings defaultResolver="artifactory"/>
	<credentials host="localhost" realm="Artifactory Realm" username="admin" passwd="password"/>
	<resolvers>
		<ibiblio name="artifactory" m2compatible="true" root="http://localhost:12000/artifactory/repo"/>
	</resolvers>
</ivysettings>
 
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="./config/ivy/ivy-doc.xsl"?>
<ivy-module version="1.0">
	<info organisation="de.telekom.flexprod" module="ivy-test" />
	<dependencies>
		<dependency org="org.slf4j" name="slf4j-api" rev="1.7.5" >
			<artifact name="slf4j-api" type="jar" />
		</dependency>
		<dependency org="org.slf4j" name="slf4j-log4j12" rev="1.7.5">
			<artifact name="slf4j-log4j12" type="jar" />
		</dependency>
		<dependency org="log4j" name="log4j" rev="1.2.17">
			<artifact name="log4j" type="jar" />
		</dependency>
	</dependencies>
</ivy-module>
 
package eu.christophburmeister.testapp;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class EchoTest{

	/** The logger. **/
	private static Logger logger = LoggerFactory.getLogger(EchoTest.class);

	/** Ctor. **/
	public EchoTest(){
		String var = "blabb";
		logger.info("blubb {}", var);
	}

}

In maven-style this script will create a target-directory, download a fresh ivy-jar from public maven-repo, uses the ivy-settings to connect to local artifactory-mirror and load all required (incl. tranisitives) to target/dependencies, where the jars can be referenced by the classpath of the javac-task in the main-buildfile.
If you sit behind a proxy, use „ant -f build.xml -autoproxy“.