Apache Maven 1.x has reached its end of life, and is no longer supported. For more information, see the announcement. Users are encouraged to migrate to the current version of Apache Maven.

Migrating from Ant

A common question is how to migrate an existing Ant build to Maven. The first section of this guide will help in some small ways to do that. It will not touch on the reasons for using Maven over Ant, or whether Maven or Ant is better for your project - these issues are discussed below in Maven for Ant Users.

If you are looking for some tips on how to do certain things you may have been doing in Ant, see the relevant section of the FAQ.

Getting Started - Creating a Project Descriptor

Sometimes people want to get their feet wet with Maven by using it to do the standard things, but to use their existing Ant build that is working fine for complex tasks. This is possible.

To do anything with Maven, you will still need to set up a project file with the information you need to do the Maven tasks you are using.

Even when you are already using Ant, this project file can be set up like any other new project. For a tutorial on doing so, see the Getting Started guide to creating a project.

Using Existing Libraries

Often, an Ant project will look for dependent libraries to add to the classpath in a known location on the filysystem (often a subdirectory of the build checked out of source control along with the source code). In some cases, the <get/> task is used to retrieve them remotely.

It is recommended that you establish repositories and let Maven take care of this. If the dependencies are not in the Maven central repository, set up an internal repository. Publish your resulting artifacts to that repository also.

However, if there is a necessity to maintain the file based approach, or you wish to start with that to keep the number of changes down, you can use JAR overrides to have Maven look for dependencies on the file system. For more information, see Handling Dependencies.

Calling Ant Scripts from Maven

In the same directory as this project.xml file (and probably in the same place as your ant build) you should create a maven.xml file like so:

<project xmlns:ant="jelly:ant">
  <goal name="do-ant-bit">
    <ant:ant dir="${basedir}" antfile="build.xml" />
  </goal>
</project>

You could then run maven do-ant-bit to run the old ant script. Ok, so this isn't that useful yet, but it can be used in conjunction with hooks to start merging an old Ant and new Maven build.

For example, consider you are now building your site with Maven. However you have an old part of your Ant build that generated a few HTML pages that you want copied with the site. Here is a possible solution.

<project xmlns:ant="jelly:ant">
  <preGoal name="site">
    <!-- Set the property html.dir that your Ant build uses to put the HTML into -->
    <ant:property name="html.dir" value="${maven.docs.dest}" />
    <ant:ant dir="${basedir}" antfile="build.xml" target="generate-html" />
  </preGoal>
</project>

Building on your Maven Project

Once these fundamentals are in place, the next steps of integration would be to start importing small Ant fragments from your existing build into your maven.xml, or for larger tasks make them reusable and create a Maven plugin that will be available to all your projects.

Some tasks may already have a complete equivalent in Maven (eg, creating a JAR), so you can remove that section from the ant script altogether.

The easiest way to use the Maven features while still executing the existing build at the appropriate time is to use goal hooks like the one given in the previous section. For more information on these, see Customising Goals in the Scripting Reference.

After this, your build will continue to grow like any other Maven build would. For information on how to do this, see Customising Maven and the Scripting Reference, as well as other sections in this User's Guide.

Maven for Ant Users

This section is intended to answer the commons questions of someone that is familiar with Ant, and wants to learn what the equivalent concepts and the differences in Maven are, and where each product excels.

While there is a strong slant towards Maven, this is NOT a guide designed to bash Ant, a remarkable and fine product. This guide IS for helping an Ant user understand the remarkable and powerful capabilities within Maven.

Different Objectives

It is important to realise that Maven and Ant have different objectives. For clarification, it is worth reading What is Maven? to learn what Maven is, and what Maven is not.

You may have heard that Maven is just Ant plus dependencies, or a set of reusable Ant scripted plugins. But in fact, the aims of the two products are quite different. There are other solutions that bring reusable fragments and dependencies to Ant 1.6 - but these do not make Maven redundant because, aside from the many other features Maven also has, it actually takes a different approach.

Build Knowledge

One of the fundamental differences between Ant and Maven is in whose responsibility it is to understand the build process and the tools used therein.

With Ant, it's the developer who must understand what the tool is and how it applies to their development. With Maven, build process knowledge is captured in plugins, small snippets of processing that rely on you providing some information.

For example, to compile your java code using Ant, you must first write a build.xml file which uses Ant's javac task, passing that task the correct set of parameters.

...
<!-- compile Java source files -->
<target name="compile">
  <javac srcdir="./src;./test" destdir="./bin" debug="on" optimize="off">
    <classpath>
      <fileset dir="lib" includes="*.jar"/>
    </classpath>
  </javac>
</target>
...

You'd then call this build.xml file using ant from the command prompt:

ant compile

This isn't too hard to do, and as you move from project to project you become better at this, and understand Ant better, learning what each of the options are for and what the best way to write these snippets is.

Maven, however, takes a far more declarative approach. You must provide Maven with some information about your project (in a file called project.xml), one piece of which is your source directory that stores your java code.

...
<build>
  <sourceDirectory>src/java</sourceDirectory>
...

To compile your code, you just need to specify that you have a source directory and then ask Maven to compile using:

maven java:compile

There's no need for the developer to understand how to write a plugin to use one. And several plugins can share the same information. For example the plugin that checks that source code conforms to a coding standard uses the same sourceDirectory as the plugin that compiles code.

This abstraction also ensures consistency. No matter what project you are building, java:compile will compile the source code, the source code is easy to find, and the output is always in the same place (target/classes).

Best Practices

Another key difference in philosophy is that of best practices. Ant is a very flexible tool - because you can break your build down into targets, which is further composed of discrete tasks you can combine them in many ways to build your project.

While Maven still allows this flexibility, because it is built around a standard set of functionality and uses metadata with sensible defaults to the describe a project, it attempts to enforce the use of best practices in composing the project's build. These best practices have been built up from the collective experience within the community.

Some examples of what Maven does in this regard are:

  • Standard locations for source files, documentation, and output
  • A common layout for project documentation to make finding information easier
  • Retrieves project dependencies from a shared storage area, instead of keeping multiple copies of a JAR in CVS
  • Encourages the use of a single source directory, but a separate unit test source directory

More than the Build - Project Knowledge

Maven also aims to go beyond the building of a project from sources, and encapsulte all of the project knowledge in one area. This includes the source code and the documentation, but also includes reports and statistics on the code and the processes surrounding management of the code.

Maven not only handles building the code, but can handle the release process, integrating closely with source control to get a clean copy to build before releasing a new version that is also deployed for others to use.

Maven is able to integrate with a large number of different products such as issue tracking, source control systems, reporting systems, application servers and software development kits. While Ant also has (and provides) much of this integration, Maven continues to use its declarative style of set up that means there is less and sometimes no work to set up these new integrations.

Terminology

This section covers what different components are called in each of Maven and Ant.

Project

In Ant a project is what you define in your build.xml file. This project is a collection of targets, which are composed of tasks.

In Maven a project is what you define in your project.xml file. It's a collection of information about the development effort that Maven uses to produce an artifact such as a JAR or WAR. Only a single artifact is built in a project: if you have multiple components to a project you build them together as a set.

Target

A target is the unit of execution for Ant. When you execute Ant, you provide a list of targets to run, e.g.

ant clean compile

This executes the clean target followed by the compile target that you have coded in your build.xml file.

In Maven, the goal is the equivalent of a target, e.g.

maven clean java:compile

This executes the clean goal of the clean plugin, followed by the java:compile goal of the java plugin.

Maven goals can be pre-defined in plugins as above, or you can define your own in a maven.xml file. In Maven 1.x, goals are written in Jelly, and can utilise any Ant tags from the version of Ant provided with Maven.

Build file

When writing your own code in Ant, you place the targets in the build.xml file.

When writing your own code in Maven, you place the goals in the maven.xml file. However, if you are only using standard Maven goals, you may not even need a maven.xml file.