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.
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.
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.
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>
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.
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.
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.
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
).
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:
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.
This section covers what different components are called in each of Maven and Ant.
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.
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.