JaVa
   

Maven Primer

The easiest way to get started with Maven is to first download and install the latest version; as of right now that is Maven-1.0-rc1. A final release is expected soon. First go to the Maven Web site and click on the download link at the top. From there you can choose the most appropriate download for your platform (EXE for easy Windows install, zip for Windows DIY install, and Tar-gzip for Unix). Once you've downloaded the file you can either extract the Zip or Tar-gzipped file onto your system or double-click the EXE file for installing. Instructions for installing each of these can be found at http://maven.apache.org/start/install.html. If you wish you can also install Maven from source, but depending on the status of the project this can be a painful process. Instructions for installing from source can be found on the Maven site at http://maven.apache.org/start/bootstrap.html.

Installing on Unix

To install Maven on Unix or a Unix-friendly operating system (OS X, Linux), retrieve the tar.gz file from the download section. Once you have downloaded the tar.gz file (tape archive, gnu zipped) to your local machine, unpack it using either gnutar or your favorite archive-handling software (OS X comes equipped with StuffIt, which will automatically unzip and untar your downloaded files for you). Once you have unarchived the file, you should be left with a folder called maven-1.0-rc1 (or another name that reflects the version you downloaded). You can place this folder anywhere on your system that you have read and write access to. Note the location for the next step. At this point you should add an environment variable called MAVEN_HOME to your startup or login shell script. We leave this exercise to since different shells have different methods. In OS X, you do this by adding a setenv command to your .tcshrc file (if you are using tc shell), which looks something like this:

setenv MAVEN_HOME /Users/me/maven-1.0-rc1


Then you may also wish to add this to your PATH statement like so:

setenv PATH ${PATH}:${MAVEN_HOME}/bin


This line adds the Maven binaries to your executable path for the user that you are logged in as.

Installing on Windows

If you are running Windows 95/98/2000 or XP, then you should download the Windows executable. It essentially does the same thing as the tar.gz file, but the EXE places Maven in your Program Files directory for you, rather than having you choose where to put it. You may also choose to download the zip file; if you go this route, then follow the directions for the Unix installation given earlier. Adding system environment variables will vary depending on which version of Windows you are running. For Windows 2000 you can add system variables by right-clicking on My Computer and choosing Properties. From there select the Advanced tab and then click the Environment Variables button. Now you have two options: System variables or User variables. For ease of use, I recommend choosing System variables just to make sure that the command-line sees the variable properly (this may vary from version to version). To add the Maven binaries to your PATH statement, double-click on the PATH entry and go to the end of the line. Add the following after typing a semicolon to end the previous PATH statement:

%MAVEN_HOME%\bin


Verifying the Install

To verify that you have Maven installed properly, go to a command line, change to your project directory, and type maven –g. This command runs Maven and outputs all the goals available to you. You can think of goals as Ant targets, except that these goals are available to all of your projects, not just to some custom-defined target that you created for Ant. You should see something like this:

Java Click To expand

If you experience connection problems, perhaps you aren't actually connected, in which case you want to run Maven in offline mode, or maybe you are connected through a proxy server. The easiest way to run Maven in offline mode is to specify it on the command line using the –o modifier, so it would look like maven –o. To specify a proxy server, the best thing to do is to specify a build.properties file in your user home directory. In this file, specify the following properties:

What was all that stuff about downloading? Didn't Maven come with everything already? Well, yes and no. What you downloaded was the skeleton of Maven. To keep it small and easy to install, it has been stripped down to exactly what it needs to run. That's not to say that what you downloaded isn't usable—it is. But a number of plug-ins are downloaded the first time you run Maven, so it's best if you're connected when you do it. Maven also checks for the latest of a particular internal dependency or plug-in and downloads that the first time it runs. Now that it has downloaded everything, Maven needs a place to put it. It handles this by default by placing your repository and extracted plug-ins into your user home (on Windows this is Documents and Settings/username; on OS X and other Unix-like operating systems it is in /etc/home/username or /Users/username) underneath the directory .maven. Calling the directory with a dot (.) in front of it hides it by default in most Unix environments (including OS X) but doesn't do anything in a Windows environment. Once you have Maven installed and you've verified that it's running, we can now dig into the fun stuff! Maven uses three files to define your project, additional properties, and custom goals. These files are:

Installing Plug-ins

If you wish to install other plug-ins not available through the Maven distribution or want to install newer versions of them, there are a few ways to go about it:

  1. Manually download and install.

  2. Install through Maven itself.
  3. Declare the plug-in as a dependency.

Manual Download and Install

To perform a manual install of a plug-in, simply download the plug-in JAR file in question and place it in the MAVEN_HOME/plug-ins directory. Maven should then automatically unjar the file and deploy it to your local .maven/plugins directory. If it does not do this, see the "Gotchas" section.

Installing Through Maven

To install a plug-in through Maven, make sure that the repository that contains the plug-in is specified in your maven.repo.remote project property. If it isn't Maven won't know where to find the plug-in.

maven plugin:download -DartifactId=cactus-maven -DgroupId=cactus -Dversion=1.6dev-20040226


This code tells Maven that we want to download the cactus-maven plug-in, version 1.6dev-20040226, and install it to our local repository.

Declaring the Plug-in as a Dependency

By declaring a plug-in as a dependency, you enable Maven to download and install it into your plug-ins directory as long as it can find the dependency to download. If a plug-in is stored at another repository make sure that repository location is added to your maven.repo.remote property in project.properties; otherwise Maven will not be able to find it.

<dependency>
 <groupId>xdoclet</groupId>
 <artifactId>maven-xdoclet-plugin</artifactId>
 <type>plugin</type>
 <version>1.2b3</version>
</dependency>


As you can see, this is rather straightforward: We are telling Maven that we need the maven-xdoclet-plug-in, version 1.2b3, installed as a plug-in so that we can use it. Once it has downloaded and installed the dependency, we can use this plug-in throughout our code (including other projects as well).

Gotchas

Here are some items to be aware of once you have downloaded and installed the plug-ins:

Now let's look at the Project Object Model (POM). First we focus on the elements inside it that are most important to us right now, and then we look at how a Maven project is structured.

The Project Object Model (POM)

The POM is an XML file called project.xml that describes your project to Maven so that it can build the project, run the appropriate tests, and build reports. All of these are core plug-ins for Maven so there is no extra coding or tweaking you need to do; you just supply the appropriate information in the POM for Maven to get ready to go. When you run Maven in a directory that contains a project.xml file, it attempts to use that as the POM, just as Ant looks for a build.xml file in the current directory it is being run in. Here is a sample project.xml file:

<?xml version="1.0"?>
<project>
 <pomVersion>3</pomVersion>
 <name>XPToolkit Maven Test Project</name>
 <id>test</id>
 <groupId>xptoolkit</groupId>
 <currentVersion>1.0-b1</currentVersion>
 <organization>
 <name>Wrox</name>
 <url>http://wrox.com/</url>
 </organization>
 <inceptionYear>2004</inceptionYear>
 <package>com.wrox.xptoolkit</package>
 <shortDescription>Test Project for Java Tools for Extreme Programming 2nd version</shortDescription>

 <description>
 This is a simple test project to highlight the structure of a Maven project for the 'Java Tools for Extreme Programming' 2nd version tutorial shared by Wrox in its Professional series.
 </description>
 <url>http://www.wrox.com/javatools/</url>
 <issueTrackingUrl/>
 <siteAddress/>
 <siteDirectory/>
 <distributionSite/>
 <distributionDirectory/>
 <repository/>
 <versions/>
 <mailingLists/>
 <developers>
 <developer>
 <name>Rick Hightower</name>
 <id>rick</id>
 <email>rick@bugmenot.com</email>
 <organization>Arc-Mind</organization>
 </developer>
 <developer>
 <name>Warner Onstine</name>
 <id>warner</id>
 <email>warner@bugmenot.com</email>
 <organization>Sandcast Software</organization>
 </developer>
 </developers>
 <contributors/>
 <licenses/>
 <dependencies>
 <dependency>
 <groupId>test-dependency</groupId>
 <artifactId>test-dependency</artifactId>
 <version>1.0</version>
 <url>http://www.test.org/</url>
 </dependency>
 </dependencies>
 <build>
 <nagEmailAddress/>
 <sourceDirectory>src/java</sourceDirectory>
 <unitTestSourceDirectory>src/test</unitTestSourceDirectory>
 <aspectSourceDirectory/>
 <!-- Unit test cases -->
 <unitTest>
 <includes>
 <include>**/*Test.java</include>
 </includes>
 <excludes>
 <exclude>**/ExcludedTest.java</exclude>
 </excludes>
 </unitTest>
 <!-- J A R R E S O U R C E S -->
 <!-- Resources that are packaged up inside the JAR file -->
 <resources>
 <resource>
 <directory>${basedir}/src/resources/misc</directory>
 <includes>
 <include>*.xsd</include>
 </includes>
 </resource>
 <resource>
 <directory>${basedir}/src/resources/logging</directory>
 <includes>
 <include>log4j.properties</include>
 </includes>
 </resource>
 </resources>
 <jars/>
 </build>
 <reports/>
</project>


So, what does this all mean? Starting from the top level we have the project element as the root element. Every POM file needs to have this as the root element.

The project Element

Under the project element we have several top-level elements:

The dependencies Element

The dependencies and build elements are the biggest part of any Maven POM. The dependencies element describes to Maven what JARs you will need when building and distributing your project. If you have no dependencies for your project, you can simply make this an empty XML element <dependencies/>. Most won't be that fortunate, so let's look at the subelement of dependencies, dependency, and what is required in that element. One of the best things about dependencies is that the majority of them probably already reside on the Maven repository, which has been graciously hosted on Ibiblio (http://ibiblio.org). If the dependency isn't hosted and the license allows for it to be freely downloaded, then a simple request to the Maven developers will generally get the dependency installed on the repository. So, how do we describe a dependency so that Maven knows where to get it?

The build Element

The build element is the other critical section of the POM. It contains several elements that describe the build environment to Maven:

Project Properties

The project.properties file resides at the same level as the project.xml file. This file allows you to override specific Maven properties and plug-in properties for your project to use. One common property that is typically used is maven.repo.remote, which allows you to specify where your remote repository resides as an HTTP address. When overriding this property, you must separate the repositories with commas. Use the Maven repository first and then any custom repositories afterwards. The code looks like this:

maven.repo.remote=http://www.ibiblio.org/maven,http://mywebsite.com/path/to /repo


Before setting up a custom repository, make sure you understand what structure Maven expects the filesystem to follow in order for it to find any JARs that you have placed there.

maven.xml

This file describes additional goals that you may want to execute before others, such as custom goals or custom Ant tasks that have not been created as plug-ins yet. This file is a Jelly file (which we discuss later in the chapter). A maven.xml file includes several elements, starting with the top-level project element. In this element you define the default goal of your project. Here is a bare-bones maven.xml file that tells Maven to build your project by default whenever you simply type maven in your project directory:

<project default="java:compile"/>


Project Layout

Now we're going to take a look at a basic project structure that Maven recommends:

LICENSE.txt project.properties project.xml maven.xml build.properties src
 test
 java
 announcements (optional)
xdocs
 navigation.xml


The basic structure of a Maven project is a very well-defined layout. You can customize the layout to a certain degree by specifying items in the build element in addition to setting custom properties in the project.properties file. The src directory is where all of your source and configuration code will go. Place all of your custom documentation for the project in the xdocs directory. Maven automatically converts this documentation to HTML or PDF format, depending on which Maven goal you execute (either site:generate or pdf:pdf goal). Now let's examine the src directory a bit more. The src directory typically consists of at least two subdirectories: java and test. The java directory contains all of your base code for the project, and the test directory contains all of your JUnit unit tests. You can also place a conf directory in here for storing things like additional properties files or configuration files that you need copied into your final JAR or testing JAR. When Maven executes a JAR goal it will always run through the tests in the test directory. You can control what files are executed by modifying the excludes element in the unitTest section of your POM. You can optionally turn off running the tests entirely by adding a maven.test.skip=true or maven.test.failure .ignore=true property in your project.properties file. Neither of these is recommended for obvious reasons—by turning off testing you run the risk of failing code. Maven generates the following when building distributions, the project Web site, and other documentation:

target
 classes
 test-classes
 iutest-classes
 generated-docs
 test-reports
 docs
 index.html
 apidocs
 xref
 xref-test
 mail-lists.html
 team-list.html
 dependencies.html
 changelog.html
 file-activity-report.html
 developer-activity-report.html
 jdepend-report.html
 junit-report.html
 checkstyle-report.html


The target directory is where everything that gets built (source, tests, documentation, and reports) end up. Most of these can also be controlled either by setting properties for specific plug-ins or by changing elements in your POM. Maven generates a number of these documentation and report files automatically for you when you run a site:generate or pdf:pdf goal. Most of these files and folders, such as apidocs, xref, mail-lists.html, and dependencies.html, are pulled directly from the POM. Others, such as developer-activity-report.html and junit-report.html, are generated from plug-ins such as changelog and test.

As you can see, there isn't too much to setting up a project to use Maven initially. The real fun comes afterwards when you want to start doing some customization, like separating your project into discrete modules, specifying new reports to run, or adding in Ant tasks that haven't been turned into plug-ins yet. Next we're going to look at the architecture a bit so that you understand how Maven works with those files you've just supplied to it.


JaVa
   
Comments