Deploying artifacts from Apache Ant to JFrog’s Artifactory

Weltzeituhr Alexanderplatz (Berlin), own Photo (by Christoph Burmeister)

Weltzeituhr Alexanderplatz (Berlin), own Photo (by Christoph Burmeister)

In my next project, I will have to deal with a lot of modules build with Apache Ant. One of my tasks will be the integration of a modern-world-solutions for building and sharing artifacts via an enterprise repository. I prefer Artifactory from JFrog as the main-repo of a project, but the following will also work with Apache Archiva or Sonatype Nexus.
About 1 and a half year ago, I described nearly the same situation and used the exec-mechanism of Ant for the solution in that post. That works, no questions. But in this post I will focus on an integrated solution delivered by Maven itself: The Maven-Ant-Tasks.

Imagine, your original ant-build creates a build-directory and after a (hopefully) successful build, you’ll get 4 artifacts in this directory: one jar and three properties-files used for several environments (dev, test, prod). And now you want to share these artifacts with the rest of your team, or simply wants them to be accessible for you configuration- and deployment-manager. All you have to do is providing a simple build-script or extend your existing ant-build-script (build.xml) and a special lib containing the maven-ant-tasks (downloadable here). So you project-structure would look like this:

The content of your build.xml (just the part that is deployment-relevant) looks like the following:

Sample-Project to demonstrate artifactory-deployment 
via ant with maven-ant-tasks ( 
<project xmlns:artifact="antlib:org.apache.maven.artifact.ant" default="init">

	<!-- directory-properties -->
	<property name="build.dir" value="build" />
	<property name="libs.dir" value="libs" />
	<!-- maven-ant-tasks jar -->
	<property name="mvn.ant.tasks.jar" value="maven-ant-tasks-2.1.3.jar" />
	<!-- artifact-properties -->
	<property name="" value="eu.christophburmeister" />
	<property name="" value="my-artifact" />
	<property name="artifact.version" value="2.1.4" />
	<property name="artifact.type" value="jar" />
	<property name="artifact.pom" value="pom.xml" />

	<!-- remote-repo -->
	<property name="remote.repo.url" value="http://buildserver:10000/artifactory/testrepo" />
	<property name="remote.repo.username" value="christoph" />
	<property name="remote.repo.password" value="spongebob" />

	<!-- including tha maven-ant-tasks-jar into classpath -->
	<path id="maven-ant-tasks.classpath" path="${libs.dir}/${mvn.ant.tasks.jar}" />
	<typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="antlib:org.apache.maven.artifact.ant" classpathref="maven-ant-tasks.classpath" />

	<!-- init-task for coupling following tasks -->
	<target name="init">
		<antcall target="clean" />
		<antcall target="deploy" />				

	<!-- deploy-task for creating and writing a temporary pom-file and deploying the artifact beside this pom-file -->
	<target name="deploy">
		<artifact:pom id="tmp.pom" groupid="${}" artifactid="${}" version="${artifact.version}" packaging="${artifact.type}" name="${}" />
		<artifact:writepom pomRefId="tmp.pom" file="${artifact.pom}"/>
		<artifact:deploy file="${build.dir}/${}-${artifact.version}.${artifact.type}">
			<remoteRepository url="${remote.repo.url}">
				<authentication username="${remote.repo.username}" password="${remote.repo.password}" />
			<attach file="${build.dir}/${}-${artifact.version}" classifier="config-dev" type="properties"/>
			<attach file="${build.dir}/${}-${artifact.version}" classifier="config-prod" type="properties"/>
			<attach file="${build.dir}/${}-${artifact.version}" classifier="config-test" type="properties"/>
			<pom file="${artifact.pom}" />			
	<!-- clean-task for deletion of an earlier created temporary pom-file -->
	<target name="clean">
		<delete file="${artifact.pom}" />

What does this script do? It creates a temporary pom.xml (after deleting an existing one) and executes a maven-deploy to the given repo with the artifact and the three attachements.

You have to provide the jar to the libs-directory and run the above script via „ant -f build.xml init“ or simply „ant“.
Afterwards, you get following output:

Buildfile: C:\dev-env-private\eclipse-ws\ant-artifactory-deployment\build.xml
   [delete] Deleting: C:\dev-env-private\eclipse-ws\ant-artifactory-deployment\pom.xml
[artifact:deploy] Deploying to http://buildserver:10000/artifactory/testrepo
[artifact:deploy] Uploading: eu/christophburmeister/my-artifact/2.1.4/my-artifact-2.1.4.jar to repository remote at http://buildserver:10000/artifactory/testrepo
[artifact:deploy] Transferring 1285K from remote
[artifact:deploy] Uploaded 1285K
[artifact:deploy] [INFO] Retrieving previous metadata from remote
[artifact:deploy] [INFO] repository metadata for: 'artifact eu.christophburmeister:my-artifact' could not be found on repository: remote, so will be created
[artifact:deploy] [INFO] Uploading repository metadata for: 'artifact eu.christophburmeister:my-artifact'
[artifact:deploy] [INFO] Uploading project information for my-artifact 2.1.4
[artifact:deploy] Uploading: eu/christophburmeister/my-artifact/2.1.4/ to repository remote at http://buildserver:10000/artifactory/testrepo
[artifact:deploy] Uploading: eu/christophburmeister/my-artifact/2.1.4/ to repository remote at http://buildserver:10000/artifactory/testrepo
[artifact:deploy] Uploading: eu/christophburmeister/my-artifact/2.1.4/ to repository remote at http://buildserver:10000/artifactory/testrepo
Total time: 2 seconds

And you (and your team) will find the artifact in Artifactory: