ONJava.com    
 Published on ONJava.com (http://www.onjava.com/)
 See this if you're having trouble printing code examples


Developing with Maven

by Rob Herbst
10/22/2003

When the size and complexity of your project grows, a build tool is the best way to automate the steps required to generate your project. For example, in a typical Java project, each time you build you compile the Java files, jar the .class files, and generate the Javadocs. These steps can all be automated using a build tool. The make build tool was invented to work out dependencies for a build, and Ant was developed as a cross-platform, Java-centric alternative, with XML replacing the Makefile's crazy syntax.

Maven from the Apache Software Foundation will most likely become your build tool of choice after you discover its many features. Not only does it provide an out-of-the-box solution to common build-related tasks, but it also produces a "dashboard" of technical information that enables a development team to track the state of a project.

The Maven Way

As great as Ant is as a build tool, you start out each project's build script having to accomplish the same things: compiling, packaging, and testing your code. You can do anything you want, using the great tasks that are built in, but it is a blank canvas for you to fill in. Anyone that has done this a few times probably has a build script they use as a template to begin any new project. One common problem is reusability of targets, unless you are writing your own custom tasks.

Maven takes a different approach. You fill in the details of your project in an XML file, and a wealth of prebuilt functionality becomes available immediately. What's even better is that you can leverage any Ant task inside of your new Maven project.

Maven provides prebuilt "goals" that will automatically:

Related Reading

CVS Pocket Reference
By Gregor N. Purdy

The power in Maven comes from a plethora of excellent plug-ins. A list is viewable at the Maven site. For example, there are plug-ins that create EAR files and control J2EE application servers.

Another interesting feature of Maven is its use of a central repository to access the .jars needed to build your project (similar to Perl's CPAN). You list what .jars and versions you need, and Maven is intelligent enough to go and download them for you. When you run Maven for the first time, or attain a new goal, you will see console output detailing repository access to download any required .jars. This is a great feature that not only makes Maven easier to use and set up, but also saves you a lot of time and the headaches of keeping your own collection of dependencies up to date in a local directory or in your source-code control system.

Maven's ease of use comes from the declarative nature of its configuration. Out of the box, it provides the basic steps that every project needs, and configuration customization is done declaratively in the file that contains your Project Object Model (POM). The POM is XML-based, with clear and descriptive names of the elements and attributes. This makes the editing process easier for the developer. Once you have completed filling out the POM, a large number of prebuilt plug-ins are ready to provide some amazing functionality to your build process.

Maven is also easily customizable, especially if you already know Ant. You can add new functionality or hook into existing processes to add any custom steps by using Ant tasks. Use the maven.xml file to add your custom functionality.

Maven Overview

The unit of work in a Maven project is a goal. For example, when you issue the command:

maven site:generate 

You are instructing Maven to attain the generate goal of the site plug-in. If you would like to see a list of all the goals at your disposal, enter:

maven -g

For any development team, running the maven site:generate goal and publishing the results on a scheduled basis gives every member of the team a clear view of the status of the project. The first page to look at is the Unit Test report, which gives the team an aggregate dashboard-style report of the test runs.

The Checkstyle plug-in is great for enforcing a coding standard. The generated reports list the summary details of how many errors exist in how many files, followed by a listing for each file of the error and line number. It provides a link to the cross-referenced source code, which makes it easy to track down any offending code.

In fact, the Maven developers use Maven in their own development, so you can check out the results of Checkstyle for Maven itself on their Checkstyle report page, as shown in Figure 1.

Figure 1. Checkstyle Report overview
Figure 1. Checkstyle Report overview

Under this summary is a line-by-line report on style violations, organized by source file, as shown in Figure 2.

Figure 2. Checkstyle Report details
Figure 2. Checkstyle Report details

The CVS plug-ins give you a quick status of the code commits to the repository. The provided reports include:

These reports are also available for Maven's own development, and a recent Changelog Report is shown in Figure 3.

Figure 3. Changelog report
Figure 3. Changelog report

Trying It Out

If you are ready to try using Maven, here are the steps to take to set it up on your system.

Now, if you enter the following command:

maven -v

You should see the following output:

 __  __
|  \/  |__ _Apache__ ___
| |\/| / _` \ V / -_) ' \  ~ intelligent projects ~
|_|  |_\__,_|\_/\___|_||_|  v. 1.0-beta-10

Not only is Maven working, but you get cool ASCII art as well! To see what options are available when you invoke Maven, type:

maven -h

To see the list of available goals, type:

maven -g

What you see in the output is a long list of plug-ins and the goals they provide:

Available [Plugins] / Goals
```````````````````````````
[ant] : Generate an Ant build file
  generate-build ............. Generate an Ant
                               build file

[antlr] ( NO DEFAULT GOAL )
  generate ................... Generate source 
                               from antlr grammars
  prepare-filesystem ......... Make any necessary
                               directories for antlr
                               processing

Further down in the list, you will see the plug-in [wizard], with the goal ui. You would attain that goal by typing the following command:

maven wizard:ui

When you type this, you'll see output messages indicating Maven is going to its repository and downloading any needed .jars.

To get more familiar with Maven, let's create a sample project. For this example, we'll create a directory called maven-sample, in ~/maven-sample or C:\maven-sample. Then run the following command:

maven -D package=com.oreillynet.mavensample genapp

This will generate a complete simple startup project for you. Make sure you enter the package name as specified above when prompted at the console. If you don't, you will get compile errors.

Now run the command:

maven site:generate

This instructs Maven to generate the site for the project. This is generated based on the POM file (project.xml) that was configured. When you run this command for the first time, you will notice that Maven goes to its own repository and downloads any .jars that are needed.

By running that one goal, Maven has compiled your code, copied over any resources (properties files) from the conf directory into your classes directory, produced Javadoc documentation, and run all of the project comprehension and analysis reports. That's an incredible amount of functionality for one goal!

If you look in the target directory, you'll see the output of the site:generate goal. Open the docs directory under target, and open the index.html in your favorite web browser. You will see the reports Maven generated for the sample application.

Ant Tasks in Maven

To integrate any Ant task into your Maven build process, you need to create a file called maven.xml in the same directory as your project.xml. Add the following XML code to the maven.xml file:

<project default="myGoal">
  <goal name="myGoal">
    <echo>Hello Maven!</echo>
  </goal>
</project>

The <echo> task is a simple Ant task that just displays the text between the tags when the task is run. When constructing your own goals in Maven, you can use any valid Ant task.

Save the file, then run the following command from the directory where your project.xml and maven.xml files reside.

maven

You should see the following output:

myGoal: 
   [echo] Hello Maven!
BUILD SUCCESSFUL
Total time:  1 seconds

Customizing Maven

Now that you have seen the basic sample project working, you can start customizing Maven for your own project's needs. If you open up project.xml in your favorite text editor, you will see the generated and commented file. You can use this as a base for your own projects and edit the file as necessary. What's nice about this approach is that you have a working project right from the beginning, and can then add your source code and other resources to the project.

If you are using the Checkstyle plug-in, you can set what coding style you would like to use in the project.properties file. This plug-in, by default, comes with the standard Sun and Turbine coding styles. If your team's style is different, you can define your own! First, set maven.checkstyle.properties=team-checkstyle.xml.

This tells the plug-in to look for a file called team-checkstyle.xml that contains the settings for your team's style. To create yours from scratch, you can use the excellent Eclipse plug-in, or use one of the standard ones and customize it. Open the MAVEN_HOME/plugins directory and then extract the files from the maven-checkstyle-plugin .jar. Under the expanded .jar's plugin-resources directory, you will see sun_checks.xml and turbine_checks.xml. Pick the one that is the closest match to your team's style and then alter as needed.

To change some of the default colors used when the project site is generated, you can change the following properties in the project.properties file. You specify the colors in the typical HTML style. In this case we have set the section, banner, and source colors.

maven.ui.section.background=#cfcfbb
maven.ui.banner.border.top=#cfcfbb
maven.ui.banner.background=#cfcfbb
maven.ui.source.background=#cfcfbb

If you need to define a dependency that is used in your company but is not available in the Maven repository at ibiblio.org, you can define the dependency like this:

<dependency>
  <id>SomeJar</id>
  <jar>someJar1.2.jar</jar>
</dependency>

You then need to place a someJar1.2.jar file in your repository. This directory location is controlled by the maven.repo.local property in your project.properties file. This defaults to ${maven.home.local}/repository, which in turn resolves to ${user.home}/.maven. If you would like to customize the reports that get generated, then add the following <reports> element to your project.xml:

<reports>
  <report>maven-checkstyle-plugin</report>
  <report>maven-changelog-plugin</report>
  <report>maven-developer-activity-plugin</report>
  <report>maven-file-activity-plugin</report>
  <report>maven-javadoc-plugin</report>
  <report>maven-jdepend-plugin</report>
  <report>maven-junit-report-plugin</report>
  <report>maven-jxr-plugin</report>
  <report>maven-statcvs-plugin</report>
  <report>maven-simian-plugin</report>
</reports>

All but the last two of these reports are generated by the standard configuration. This adds maven-statcvs-plugin, which generates statistical cvs reports, and the maven-simian-plugin that identifies duplicated lines of code in a project. Once you define a <reports> element, you override any of the reports that would get generated by default.

Conclusion

This article has provided a basic introduction to the features of the Apache Maven project. Using Maven should help streamline your team's build process and give you insight into the current status of your code.

Maven's developers, and the community of users, have created an excellent build tool. Thank you!

Rob Herbst is a developer whose interests include Java, Linux, and .NET


Return to ONJava.com.

Copyright © 2009 O'Reilly Media, Inc.