Frequently Asked Questions
- What is Maven?
- What problems does Maven solve?
- How is Maven different from other typical solutions to these problems?
- How does Maven do what it does?
- Is there a good sample POM?
- What other kind of cool things does Maven do?
- What do we need to make Maven work?
- What considerations exist for using Maven as I develop code?
- What considerations exist when we use Maven as we run an autobuild?
- Does Maven play nice with Ant?
- Does Maven play nice with CruiseControl?
- Where can I get more information?
What is Maven?
Maven is a tool to build Java projects. At its simplest, it could be considered a competitor to the most basic Ant features. Some Maven-related tools could be considered competitors to CruiseControl. And Maven does a bunch of things that those tools don’t.
What problems does Maven solve?
There are a few problems that Maven solves:
- When projects use a variety of open source .jar files, developers need to get copies of those .jars and keep the jars available to build the code.
- Conversely, we reinvent the wheel rather frequently, and having a convenient mechanism to make code available for reuse, and to consume that code, would help to mitigate that problem.
- Usually, there are two “descriptions” of how the project is compiled: there’s a set of Eclipse-specific files (like the .classpath and .project files) and an Ant build.xml. Sometimes, developers commit to the repository with those things being out-of-synch, and some poor soul who is stuck with being “the build guy” has to fix the build.xml.
- Often, there’s a lot of boilerplate stuff (that is to say, parts that are often “cut and paste” reused) in Ant build.xml files: compile stages, run the tests tasks, package the code. Smaller projects, in particular, might only have boilerplate build files. This stuff is usually verbose and only really understood by a minority of people on a project.
- On larger projects, there are a variety of build-time tasks that people hope to do, but which often fall by the wayside. For example, most projects wishfully intend to put Code Coverage steps in their build, but that’s one of those things we’ll get around to real soon now…
- Most project rooms have a machine sitting in the corner that’s dedicated to building the project. Small projects that no longer have development teams have usually lost their build machines to active projects.
How is Maven different from other typical solutions to these problems?
The primary difference between Maven and tools like Ant/CruiseControl is that Ant allows you to configure anything you want, but you always have to do some work to setup that configuration. The number of things that Ant can do is unbounded, but more stuff takes more work (and more maintenance).
Maven, on the other hand, follows the principle of “convention over configuration”, which means that a developer only needs to specify the unconventional aspects of their application.
Thus, Maven can do a whole lot with just some really minimal information, as long as you follow some relatively straight-forward conventions (such as putting your source code in a particular directory structure). In addition, Maven has an explicitly defined concept of a project’s Build Lifecycle(including phases like: validate, generate-sources, compile, test, package, integration-test, verify, install and deploy). Thus, to compile a .jar project in Maven, the command is always “mvn compile”, whereas in Ant, this target can be called anything you want. In other words, Ant forces you to re-invent and implement a lifecycle for each project.
Another difference between Maven and other tools, is that in Ant environments, you usually end up with .jar files checked in to the CVS repository (where Ant can find them to use them in the build). Maven, on the other hand, has this idea of there being a set of repositories from which it gets the .jar files that it needs to build the project.
How does Maven do what it does?
Much of Maven’s functionality is driven by a set of conventions combined with a single source for most of the meta-data for a project. That meta-data is provided by each project’s POM (an acronym for Project Object Model) file, which provides a declarative description of a project in a single xml file, named pom.xml.
Maven keeps a “local repository” on your file system, and if it can’t find a .jar in that local repository, it’ll go off to some remote repositories that it knows about and download the .jars to your local repository. These jars are never checked in to CVS, which helps remove some clutter.
More interestingly, Maven can also get code from remote repositories, and it can publish code that you develop to such repositories for other team members to use. There’s a centralized main Maven repository at ibiblio.com to which most major open source projects submit builds of their code, and a search engine that you can use to find the right stanza to drop into your pom.xml for the version of the package that you want in your project.
Maven uses a plug-in architecture built around a simple framework. Like Eclipse, Maven does all of its useful work in plug-ins, rather than built-in features. The plug-ins are themselves deployed to the central repository, so when you first download Maven and try to run a goal such as mvn install, Maven will go out and download the most recent version of your plug-in for you to use. There’s a plug-in to compile your Java code, a plug-in to run your unit tests, a plug-in to create an Eclipse project for you, and so forth. There’s even a plug-in to let you build and deploy plug-ins.
When you start a build through mvn install or a similar target, Maven looks at your POM, grabs the POMs of all of the dependencies that you specified, and then transitively grabs all of the POMs from the dependencies, and so forth. If several packages that you depend on all want versions of the
same artifact, Maven will try to come up with an acceptable version that will satisfy them all, based on the dependency information supplied in the POM. Then, with a full list of everything that your project needs, Maven goes out to the repositories that you specified, downloads the .jars and other related artifacts, and uses them to build your project.
In addition to just building your code, you can make Maven run your tests, gather code coverage information, and so forth, by specifying additional attributes to the build section of your POM. Maven’s dependency mechanism works strictly based on group and artifact IDs and by version numbers. It does all of its analysis based on information supplied in the POM, and doesn’t attempt to infer anything by looking at your code, for example. You can specify ranges of acceptable versions for your dependencies, or specify specific fixed versions, and you can force the dependency analysis mechanism to exclude certain portions
Is there a good sample POM?
What other kinds of cool things does Maven do?
In addition to building your code, running tests, and so forth, Maven can also pull together an informational website about your project, using the mvn sitetarget. You can add documentation to your site using a wiki-like syntax known as APT (“almost plain text”), and through directives in your POM, you can cause the site to include use information such as a change log generated from source control, your Javadoc, a code coverage report, and so forth.
Maven supports the concept of an “archetype”, which lets you quickly pull together a new jar, web application, or other project simply by running a command or two. You can define your own archetypes (for example, a web application using our standard Spring/Hibernate/Tapestry stack), which will produce a correctly-structured project with a POM that contains all of the relevant dependencies. You can find an example of using an archetype here.
Maven includes plugins that let you quickly bring up your web application for testing. mvn jetty6:run, for example, will bring up your application in Jetty. Maven also has a system called “Cargo” that can let you deploy your application to a production (or test) server.
What do we need to make Maven work?
At the very least, you need to install Maven on your developer workstation. Follow the instructions over here to install Maven.
You’ll also want to go to Eclipse and configure your Eclipse workspace with a bit of knowledge about where the Maven repository exists. We do this by setting an Eclipse classpath variable. Maven by default creates a local repository for you at C:Documents and Settings<your user name>.m2repository; you need to set the M2_REPO classpath variable in Eclipse to point to this value.
Obviously, we tend to use Eclipse as the “builder of choice” when we develop applications. Even if we have Maven, our usage pattern for Eclipse is probably not going to change a whole lot. In general, you’ll do most of your development as usual, and only have to care about Maven when you add or change dependencies in your project:
- Check your project out of source control and fire up Eclipse.
- Add some dependencies to the Maven pom.xml file.
on the command line, and the net result is that the Eclipse files (like the .classpath and .project) are updated to reflect the dependencies, and to point to the .jars in the local Maven repository.
- Refresh the project in the Eclipse workspace.
In this environment, whenever the dependencies change, the same Maven commands need to be executed to update Eclipse.
Alternatively, there’s a plug-in to Eclipse that allows Eclipse to interpret the Maven pom.xml file directly. It’s not very stable, and its use is not recommended, but future versions might be stable enough to use, which would obviate the need to keep rerunning the eclipse:eclipse target whenever dependencies change.
What considerations exist when we use Maven as we run an autobuild?
If all you want to do is compile the source, jar it up and run the tests, then Maven can handle all of those basic tasks without the need to have either a build.xml or a CruiseControl environment.
There is an internal build machine (using a Maven competitor to CruiseControl called Continuum) that can be shared by multiple projects. All you have to do to set up an autobuild is to log in to the Continuum site, and upload the POM from your project. By default, Continuum will then try to build the latest version from your project’s trunk every five minutes, using mvn install as its target. You can change the target (if you want to deploy your autobuilt snapshot, for example), add additional builds on different schedules (to re-publish and re-deploy your site daily, for example), change your build schedule (checking hourly, for example, rather than every five minutes), and so forth.
Does Maven play nice with Ant?
You can use Mavenized dependent projects in the build of a non-Mavenized project’s build.xml through the “antlib” mechanism. Antlib will go and fetch the appropriate dependencies (transitively) from your Maven repository, and turn them into an Ant fileset that you can run targets against. For more information, see http://maven.apache.org/ant-tasks.html . Conversely, you can use the antrun plugin to run Ant tasks as additional goals at build time.
Does Maven play nice with CruiseControl?
Yes. Cruise Control natively understands Maven out of the box, and can use Maven as its build tool in place of Ant. You can configure your Cruise Control configuration file with a <maven2snapshotdependency> tag that points to your POM file, and Cruise Control will automatically trigger itself when it detects a committed change. See the Cruise Control documentation for more details.
Where do I get more information?
Maven has quite a bit of its own documentation at http://maven.apache.org .