Have you ever been assigned to an existing project where the original programmers are nowhere to be found? Or given source code from a third party and told to fix a bug, only to find there isn't any decent documentation? Avoid some of these resulting headaches by using Maven to generate code-level documentation for your projects. Maven ties together a build management system and various third-party source code analysis tools to help you get your projects out the door faster.
Maven is a project-oriented tool from the Apache Jakarta Project that builds upon Jelly (see the Jelly Website), Ant, and other open source projects to give developers a complete picture of their projects. Maven bundles many open source projects under one umbrella to let developers easily integrate these third-party tools into their build processes. Maven uses plug-ins for various tools, including:
- Ant for build management
- JUnit for unit testing
- Jalopy for formatting source code
- Checkstyle for validating Java source against a coding standard
- Sun's javadoc for standard JDK code documentation
For a complete list of Maven's functionalities, check the plug-ins page on the Maven Website.
The Krysalis Centipede project achieves similar goals. An open source build tool based on Ant, Centipede features cents, which are equivalent to plug-ins, and includes many of the same tools as Maven, along with some that Maven omits. Discussions in the Jakarta Project mailing lists have focused on how the two could work together moving forward. If you decide to evaluate Maven, also evaluate Centipede; either one could be appropriate for your project.
In this article, I discuss some key Maven concepts to give you an idea of how Maven works and then launch into a walkthrough of an example
project.xml file from a project already using Maven: the Jakarta Project's Torque, which is an object-relational database tool. You should be able to adapt the Torque example for your own use by simply changing some values to match your existing configuration and project setup.
Maven's central concept is that all code belongs in projects, each one defined by a project descriptor. These projects are either discrete components or a full application that can be built on its own with various dependencies. The descriptor consists of a Project Object Model (POM), which can be a
project.xml file, or another storage format such as a database. The XML format for the POM is specified by the
maven-project.xsd XML Schema file in your Maven installation's root directory. Generally speaking, copying an example
project.xml file from an existing Maven installation and customizing it for your own needs proves easier than creating a new one from scratch.
Maven defines some common goals for projects. Goals resemble Ant targets; you use them to generate source code documentation, compile your application, unit test the compiled project, or run the plug-ins shipped with Maven. To find a project's available goals, run the command
maven -g in the directory that contains your
project.xml file. This command will return a list of plug-ins and their defined goals. A sample of this output:
[java] ( NO DEFAULT GOAL ) compile .................... Compile the project jar ........................ Create the deliverable jar file jar-resources .............. Copy any resources that must be present in the deployed JAR file prepare-filesystem ......... Create the directory structure needed to compile [javadoc] : Generate API documentation generate ................... Generate API documentation [jdepend] : Generate a dependency report with JDepend generate-report ............ Generate a dependency report with JDepend [junit-report] : Generate a report from the test results
The names in brackets refer to installed Maven plug-ins, with their goals listed underneath. To run the javadoc generate goal, call Maven from the command line with the following syntax:
maven javadoc:generate. As it turns out, generate is the javadoc plug-in's default goal, so you can also run it with this command:
maven javadoc. However, don't rely on that command for the generate goal.
Additional goals and processing can be defined in the
maven.xml file, which is specific to each project. File
maven.xml should reside in the same directory as
project.xml. Goals originate from the Werken Company's open source werkz project. As mentioned earlier, each goal is identical to an Ant target, except that
<goal> replaces the Ant
<target> element. The
<goal> element has attributes for a name and a description. It can also have a list of prerequisite goals, much like Ant has targets that require other targets to run. The
prereqs attribute specifies these goals. Here is an example goal declaration from the Torque 3.0 beta 4
<goal name="runtime:prepare" prereqs="java:jar">
Goals can also use the
attainGoal command to run a goal directly. An example would look like this:
You can also extend a goal so that pre- or post-processing occurs before or after the goal runs. This proves useful for extending Maven's built-in goals, for example, to archive an old jar file when a new build is created. Instead of using
<postGoal>. These dependent goals use the same syntax internally.
Maven has a strong dependency system for projects as well, although the implementations are quite different. Projects can share dependencies—mostly used for ensuring that every project uses common jar files. For instance, each of your projects may rely on the Jakarta POI jar file; Maven keeps each project current with the latest jar file.
These jar files are retrieved from a repository, which is a directory on a remote Web server that contains all jar files. The jar files are mirrored in a local repository under the Maven installation. The remote repository location is configured in the
driver.properties file located in your Maven installation's
bin subdirectory. A property called
maven.repo.remote takes a comma-separated list of URLs. By default, Maven uses http://www.ibiblio.org/maven as its repository. You will need to set up your own repository with copies of internal jar files, private builds of open source projects, and other resources you might need. Additionally, Maven uses an XML element called
repository in the
project.xml POM to refer to the source control repository your project uses for storing its source. Maven's source control repository attribute supports CVS (Concurrent Versioning System) and Subversion, an open source Java source control system.
Use Maven to build your project
Once you have your
maven.xml files set up for your project, just run Maven from the command line in the directory that has those files. Maven will download the appropriate jar files to its local repository. Maven then creates a target directory (called
target) for its output. Maven uses javac to compile the source directory's contents to a subdirectory called
classes under the
target directory. Maven then fires off the unit tests configured under the build element in
project.xml. If those tests succeed, Maven will create a jar file with the project's name and version in the
Use Maven to create documentation for your project
Maven can also generate an impressive Website for your project. Run the
site:generate goal for your project with this command:
Maven will create a new subdirectory under
index.html in your favorite Web browser and surf around. Maven integrates project information, Javadocs, unit-test information, source code cross referencing, a coding style check, metrics, and more into a single static generated Website—no CGI, servlets, or anything else necessary.
Maven gets its look and feel for the generated Website from the XDoc plug-in. This plug-in is located in the
maven/plugins/maven-xdoc-plugin-1.1/ directory, and you can modify its CSS (Cascading Stylesheets), images, and XML templates. Since the Website should be used internally anyway, you won't find many reasons for modifying it, plus you would have to move any changes to a new version of Maven when you upgrade.
Download and install Maven
You can download Maven from the Maven download page, which also features installation instructions. Because Maven's installation process is constantly improving, I won't discuss it here. As of this writing, Maven remains at the 1.0 beta 6 version, and the released version's installation procedure might differ.
Example: Torque 3.0 beta 4
The Jakarta Project's Torque object-relational mapping tool uses Maven in its latest release for building and creating the Website on the Jakarta Project's site. To show you an example project, I'll walk you through Torque's
project.xml. You'll find this file in the source code that can be downloaded from the Jakarta Project; you'll find the generated documentation on the Torque project page.
project.xml included with Torque is used only by Maven and only by a developer building Torque from source or creating documentation. Developers using Torque for their own projects don't need that file. To create a
project.xml file, start with a root element of
<?xml version="1.0" encoding="UTF-8"?> <project>
<pomVersion> element, illustrated below, identifies the POM version used when this
project.xml was created. You shouldn't need to change the version. Future Maven versions will have larger numbers.
<id> element, shown below, is Maven's naming convention; for example, you can use it to name jar files. You append the current tool version to the
<id> tag's value—Torque's jar file is named
<name> is a longer version of
<id >torque </id > <name >jakarta-turbine-torque </name > <currentVersion >3.0-b4 </currentVersion >
organization refers to the project developers. Replace that element with your company's name, homepage, and a logo URL that can be used as an
<img> HTML tag's
<organization > <name >Apache Software Foundation </name > <url >http://jakarta.apache.org/ </url > <logo >/images/jakarta-logo-blue.gif </logo > </organization >
You use the
inception year for copyright notices in the Javadoc:
<inceptionYear >2000 </inceptionYear >
All of Torque's code should be under this package:
<package >org.apache.torque </package >
This is the URL for Torque's logo; it resembles the organization's logo described above:
<logo >/images/blue-logo.gif </logo >
Gump is another Jakarta Project build tool that helps build many interdependent projects. You probably aren't using it, so you can leave this element out:
<!-- Gump integration -- > <gumpRepositoryId >jakarta </gumpRepositoryId >
This description will go on the front page of the Website generated with Maven:
<description >Torque is a persistence layer. </description >
A brief description of the project:
<shortDescription >Persistence Layer </shortDescription >
<url> element is the project's homepage:
<url >http://jakarta.apache.org/turbine/torque/ </url >
Include a link to your bug tracker if it's Web-based:
<issueTrackingUrl >http://issues.apache.org/scarab/servlet/scarab/ </issueTrackingUrl >
Maven can optionally deploy the generated Website to another Web server, using the
site:deploy goal. Set the values of the XML elements below to your Web server's name and filesystem path:
<siteAddress >jakarta.apache.org </siteAddress > <siteDirectory >/www/jakarta.apache.org/turbine/torque/ </siteDirectory >
Similar to the above code, Maven can publish the entire distribution it creates to the Web server using the
<distributionDirectory >/www/jakarta.apache.org/builds/jakarta-turbine-torque/ </distributionDirectory >
Below is the source control repository I discussed above. It only works with CVS. Modify this code to use your CVS connection string if you have one. The URL proves useful if you run WebCVS or another Web-accessible CVS server; developers that visit your site don't have to load CVS or a GUI (graphical user interface) to get one or two source code files.
<repository > <connection >scm:cvs:pserver:email@example.com:/home/cvspublic:jakarta-turbine-torque </connection > <url >http://cvs.apache.org/viewcvs/jakarta-turbine-torque/ </url > </repository >
Maven creates a mailing-lists page for your documentation. Modify the value of the
mailingList XML elements below, if it has any. The
<unsubscribe> elements should be email addresses monitored by the list-manager software. The
<archive> element can point to the URL for your mailing list's back emails.