BUY THIS BOOK
Add to Cart

Print Book $29.95


Add to Cart

PDF $23.99

Safari Books Online

What is this?

Add to UK Cart

Print Book £20.95

What is this?

Looking to Reprint or License this content?


Maven: A Developer's Notebook
Maven: A Developer's Notebook

By Vincent Massol, Tim O'Brien
Book Price: $29.95 USD
£20.95 GBP
PDF Price: $23.99

Cover | Table of Contents | Colophon


Table of Contents

Chapter 1: Maven Jump-Start
Let's start using Maven. By the end of this chapter you should be able to create a Maven project from scratch, use Maven to manage dependencies, and create a simple project web site with some interesting reports.
Before you start in on this book, you'll need to install some prerequisites. While the examples in this book were written with Java 1.4.2, Maven is compatible with both Java 1.4.2 and Java 1.5.0. This book was written to the most recent version of Maven released at the time of this writing—Maven 1.0.2. In addition to the JDK and Maven 1.0.2, you will also need to be connected to the Internet, as Maven will download dependencies from a public web site as they are required. So, go ahead, install Maven.
Some of the plug-ins referenced in this Developer's Notebook are not bundled with Maven 1.0.2. Please refer to Chapter 6 and the comprehensive list of plug-ins in Appendix AAppendix A for detailed instructions on installing the required Maven plug-ins.
Download Maven from the Apache Software Foundation (ASF). Go to http://maven.apache.org/ and select Downloading from the Getting Maven menu on the left navigation menu. This will take you to a page which will let you select a Windows Installer package, a .zip file, a tar'd .bzip file, or a tar'd .gzip file. Download the distribution appropriate for your platform.
On a Microsoft Windows platform, download the Windows Installer package (maven-1.0.2.exe) and follow the instructions during the automated installation. After Maven is installed using Windows Installer, you should have a user environment variable, MAVEN_HOME, pointing to the location of your Maven installation. You will then need to add %MAVEN_HOME%\bin to your PATH by selecting Control PanelSystemAdvanced and clicking the Environment Variables button. Prepend %MAVEN_HOME%\bin to your PATH variable, and go to the command prompt by running cmd.exe. If Maven has been installed successfully, you should see the following output on the command line:
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Installing Maven
Before you start in on this book, you'll need to install some prerequisites. While the examples in this book were written with Java 1.4.2, Maven is compatible with both Java 1.4.2 and Java 1.5.0. This book was written to the most recent version of Maven released at the time of this writing—Maven 1.0.2. In addition to the JDK and Maven 1.0.2, you will also need to be connected to the Internet, as Maven will download dependencies from a public web site as they are required. So, go ahead, install Maven.
Some of the plug-ins referenced in this Developer's Notebook are not bundled with Maven 1.0.2. Please refer to Chapter 6 and the comprehensive list of plug-ins in Appendix AAppendix A for detailed instructions on installing the required Maven plug-ins.
Download Maven from the Apache Software Foundation (ASF). Go to http://maven.apache.org/ and select Downloading from the Getting Maven menu on the left navigation menu. This will take you to a page which will let you select a Windows Installer package, a .zip file, a tar'd .bzip file, or a tar'd .gzip file. Download the distribution appropriate for your platform.
On a Microsoft Windows platform, download the Windows Installer package (maven-1.0.2.exe) and follow the instructions during the automated installation. After Maven is installed using Windows Installer, you should have a user environment variable, MAVEN_HOME, pointing to the location of your Maven installation. You will then need to add %MAVEN_HOME%\bin to your PATH by selecting Control PanelSystemAdvanced and clicking the Environment Variables button. Prepend %MAVEN_HOME%\bin to your PATH variable, and go to the command prompt by running cmd.exe. If Maven has been installed successfully, you should see the following output on the command line:
C:\dev\mavenbook\code>maven -v
 _ _  _ _
|  \/  |_ _ _Apache_ _ _ _ _
| |\/| / _` \ V / -_) ' \  ~ intelligent projects ~
|_|  |_\_ _,_|\_/\_ _ _|_||_|  v. 1.0.2
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Starting a New Project
Part of the hassle of setting up a new project is the amount of effort involved in creating a "development infrastructure"—automated builds, unit tests, documentation, project reporting, etc. Using Maven, you can accelerate this process by generating a skeleton project which can be used as a seed for new applications.
Maven has an Application Generation plug-in (Genapp) which you can use to create a new project. Start by creating an empty c:\dev\mavenbook\code\genapp\test-application directory that will house the generated application. Run the Genapp plug-in by executing the genapp goal, selecting the default template, and supplying some information about your new project:
C:\dev\mavenbook\code\genapp\test-application>maven genapp
 _ _  _ _
|  \/  |_ _ _Apache_ _ _ _ _
| |\/| / _` \ V / -_) ' \  ~ intelligent projects ~
|_|  |_\_ _,_|\_/\_ _ _|_||_|  v. 1.0.2
  
Attempting to download commons-jelly-tags-interaction-20030211.143817.jar.
4K downloaded
Enter a project template to use: [default]
[Enter]
Please specify an id for your application:  [app]
test-application
Please specify a name for your application:  [Example Application]
Test Application
Please specify the package for your application:  [example.app]
mdn.testapp
build:start:
  
genapp:
    [copy] Copying 1 file to C:\dev\mavenbook\code\genapp\test-application\src\java\
mdn\testapp
    [copy] Copying 3 files to C:\dev\mavenbook\code\genapp\test-application\src\test\
mdn\testapp
    [copy] Copying 1 file to C:\dev\mavenbook\code\genapp\test-application\
    [copy] Copying 2 files to C:\dev\mavenbook\code\genapp\test-application\
BUILD SUCCESSFUL
This plug-in asks the user for some input, and from this output you can see that you are using the default application template, and you are supplying an application ID, application name, and package for the new project. The default application template creates a single class, mdn.testapp.App, with a static main function and two JUnit tests.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Using Maven Behind a Proxy
Maven relies on an Internet connection, and it downloads all dependencies and plug-ins over HTTP. If you are working in a corporate environment, you may need to configure Maven to work with a proxy server.
You will need to set some properties in your project's project.properties file. The project.properties file allows you to customize the behavior of Maven by setting named properties. To configure a proxy server, place the following project.properties file in the same directory as your project's project.xml file:
maven.proxy.host = proxy.company.com
maven.proxy.port = 80
These properties configure Maven to connect to port 80 on the proxy.company.com machine. If you are using a proxy server that requires authentication, you will need to specify two additional properties:
maven.proxy.username = tobrien
maven.proxy.password = myp@ssw0rd
And, if you need to connect to a proxy server which requires NTLM authentication, set the following properties:
maven.proxy.ntlm.username = tobrien
maven.proxy.ntlm.password = myp@ssw0rd
In Section 2.1, you will learn that such user-specific properties should be defined in ~/build.properties or %USERPROFILE%\build.properties files. For now, define these properties in project.properties if you need to complete this lab from behind a firewall.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Compiling and Testing a Project
You have a new project with one class and a unit test. Next, let's build the project and run the App class.
Create a JAR file containing this application's classes by executing the jar:jar goal. The JAR plug-in defines a shorthand goal named jar which depends upon the jar:jar goal. Executing either goal will have the same result. All plug-ins define such a shortcut; for example, the test goal executes the test:test goal from the Test plug-in. Execute the jar goal with maven jar:
C:\dev\mavenbook\code\genapp\test-application>maven jar
 _ _  _ _
|  \/  |_ _ _Apache_ _ _ _ _
| |\/| / _` \ V / -_) ' \  ~ intelligent projects ~
|_|  |_\_ _,_|\_/\_ _ _|_||_|  v. 1.0.2
  
Attempting to download junit-3.8.1.jar.
118K downloaded
  
build:start:
  
java:prepare-filesystem:
    [mkdir] Created dir: C:\dev\mavenbook\code\genapp\test-application\target\classes
  
java:compile:
    [echo] Compiling to C:\dev\mavenbook\code\genapp\test-application/target/classes
    [echo]
    [javac] Compiling 1 source file to C:\dev\mavenbook\code\genapp\test-application\
target\classes
  
java:jar-resources:
Copying 1 file to C:\dev\mavenbook\code\genapp\test-application\target\classes
  
test:prepare-filesystem:
    [mkdir] Created dir: C:\dev\mavenbook\code\genapp\test-application\target\
test-classes
    [mkdir] Created dir: C:\dev\mavenbook\code\genapp\test-application\target\
test-reports
  
test:test-resources:
  
test:compile:
    [javac] Compiling 3 source files to C:\dev\mavenbook\code\genapp\test-application\
target\test-classes
  
test:test:
    [junit] Running mdn.testapp.AppTest
    [junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.078 sec
  
jar:jar:
    [jar] Building jar: C:\dev\mavenbook\code\genapp\test-application\target\
test-application-1.0.jar
BUILD SUCCESSFUL
Total time: 9 seconds
Maven creates a target directory to hold intermediate files and JAR files. Once the JAR has been created, execute the
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Working with the Project Object Model
The Project Object Model (POM) is a central part of Maven, and you will work with it throughout this book.
The POM is also referred to as the project descriptor. The XML in project.xml describes a project's source code, developers, source control, licensing, as well as identifying information such as the name of the project and the name of the sponsoring organization. Maven's POM is a break with build systems of the past; instead of providing explicit instructions for each build, Maven uses a declarative approach to build management. In other words, you don't tell Maven what to do as much as Maven just knows where to look based on the contents of project.xml. On the other hand, Ant is an imperative approach to project builds; you end up telling Ant to compile this class, make this directory, bundle up these files into a WAR, etc. Maven maintains an assortment of plug-ins crafted to work with a standard POM—a declaration of structure, identification, and content.
If you look at the project.xml file generated by the previous exercise you will notice a number of elements which have been omitted from the previous discussion. The following XML lists the top-level elements in a POM, in the order in which they are expected:
<project>
  <extend/>
  <pomVersion/>
  <id/>
  <name/>
  <groupId/>
  <currentVersion/>
  <organization/>
  <inceptionYear/>
  <package/>
  <logo/>
  <gumpRepositoryId/>
  <description/>
  <shortDescription/>
  <url/>
  <issueTrackingUrl/>
  <siteAddress/>
  <siteDirectory/>
  <distributionSite/>
  <distributionDirectory/>
  <repository/>
  <versions/>
  <branches/>
  <mailingLists/>
  <developers/>
  <contributors/>
  <licenses/>
  <dependencies/>
  <build/>
  <reports/>
  <properties/>
</project>
This chapter explores most of the elements listed in the previous XML, including contributors, developers, dependencies, reports, and repository. The labs in this chapter will provide the details, but you should use the previous XML excerpt to place elements in the proper sequence within your
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Listing Available Goals
When you use Maven, you will be executing goals. A Maven plug-in is a set of related goals. For example, to create a JAR from a project, you would execute the jar:jar goal from the JAR plug-in as follows:
C:\dev\mavenbook\code\genapp> maven jar:jar
         
The jar before the colon separator classifies this goal as belonging to the JAR plug-in. To see a list of all the goals in the JAR plug-in, enter the following command:
C:\dev\mavenbook\code\genapp> maven -P jar
 _ _  _ _
|  \/  |_ _ _Apache_ _ _ _ _
| |\/| / _` \ V / -_) ' \  ~ intelligent projects ~
|_|  |_\_ _,_|\_/\_ _ _|_||_|  v. 1.0.2
  
Goals in jar
=  =  =  =  =  =  =  =  =  =  =  =
  
[jar]                               Create the deliverable jar file.
  deploy  ......................... Deploy a jar to the remote repository
  deploy-snapshot  ................ Deploy a snapshot jar to the remote
                                    repository
  install  ........................ Install the jar in the local repository
  install-snapshot  ............... Install a snapshot jar in the local
                                    repository
  jar  ............................ Create the deliverable jar file.
  snapshot  ....................... Create a snapshot jar, ie '
                                    id-YYYYMMDD.hhmmss.jar'
  
Plugin for creating JAR files. Requires Maven 1.0 RC2.
If you need to see a list of every available plug-in and goal, type the following:
C:\dev\mavenbook\code\genapp\test-application> maven -g | more
         
The entire list of plug-ins is a little daunting, as Maven has plug-ins for just about everything, from generating project files for different IDEs to generating WAR files to starting and stopping an application server. You will learn about some of the more useful plug-ins in the following labs.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Producing Debug Information
By now, you may have noticed that Maven is performing a good deal of heavy lifting. If you were using Ant, you would have already had to write an Ant build.xml file and added tasks to compile, jar, and unit test. Maven is hiding a good deal of complexity, but when debugging problems, it is nice to be able to look "behind the curtain." The ability to run Maven in debug mode and to have this tool print out every last detail of a build can be essential if you need to verify that a build is doing exactly what you think it is doing.
For this lab, refer to the previous test application. When running maven test, you will receive the following output:
java:compile:
    [echo] Compiling to C:\dev\mavenbook\code\genapp\test-application/target/classes
    [echo]
  
java:jar-resources:
[...]
What is really happening during the java:compile or the java:jar-resources goals? Running maven -X test will display the full debugging output for all goals executed in a Maven build. Let's try it, and focus on the three goals listed earlier. Running maven -X test produces the following output:
[...]
java:compile:
    [echo] Compiling to C:\dev\mavenbook\code\genapp\test-application/target/classes
    [javac] [DEBUG] fileset: Setup scanner in dir 
        C:\dev\mavenbook\code\genapp\test-application\src\java with 
        patternSet{ includes: [  ] excludes: [**/package.html] }
    [javac] [VERBOSE] mdn\testapp\App.java omitted as mdn/testapp/App.class is up 
to date.
  
java:jar-resources:
[DEBUG] FileSet: Setup scanner in dir 
        C:\dev\mavenbook\code\genapp\test-application\src\conf with 
        patternSet{ includes: [*.properties] excludes: [  ] }
[VERBOSE] app.properties omitted as app.properties is up to date.
[...]
The output printed by the java:compile task may look familiar. It is the output of Ant's echo and javac tasks. As explained in Section 2.1, Maven frequently uses Ant tasks to perform common operations such as copying, deleting, compiling, and creating JAR files.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Adding a Dependency
You have a project with a single class which you've successfully compiled and executed. Next, you'll add a dependency to the project descriptor and start to use Maven to manage project dependencies. For the purposes of this lab, assume that you need to work with the Spring Framework. Add a dependency on two artifacts from the Spring Framework—spring-core-1.1.4.jar and spring-web-1.1.4.jar.
First, you need to locate the JAR you need in Maven's default central repository, served from ibiblio.org at http://www.ibiblio.org/maven/. Load this URL in a web browser and you will see a series of directories; the directory we are interested in is springframework, and the structure of the subdirectories under springframework follows:
http://www.ibiblio.org/maven
    /springframework
        /jars
            spring-core-1.1.4.jar
            spring-dao-1.1.4.jar
            spring-web-1.1.4.jar
To depend on an artifact, you use three elements within dependencygroupId, artifactId, and version. You can add dependencies to both artifacts by replacing the dependencies element in test-application/project.xml with the following XML:
<dependencies>
  <dependency>
    <groupId>springframework</groupId>
               <artifactId>spring-core</artifactId>
    <version>1.1.4</version>
  </dependency>
  <dependency>
    <groupId>springframework</groupId>
               <artifactId>spring-web</artifactId>
    <version>1.1.4</version>
  </dependency>
</dependencies>
Now, run the jar goal and take a look at the output of Maven; it should contain something that looks like this:
Attempting to download spring-core-1.1.4.jar.
266K downloaded
Attempting to download spring-web-1.1.4.jar.
111K downloaded
Figure 1-1 shows the following series of events, triggered by the jar goal:
  1. Maven looked at the POM, as defined in project.xml, and saw the dependency on two artifacts in the
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Depending on Snapshots
If you are developing a program that depends on a frequently changing dependency, you might want to depend on the latest build instead of hardcoding a version for each dependency. This can be especially useful when a project depends on a dependency which is still a beta of a release candidate, or if you are developing a series of interdependent Maven projects, as discussed in Chapter 3. In this lab, you'll learn how to depend on a SNAPSHOT.
Instead of specifying a specific version in your dependency block, use the keyword SNAPSHOT as part of the version name. Every time you execute a Maven goal, Maven will check for a new version of the dependency from the remote repository. Maven will download the dependency if the remote repository has a newer version than the local repository. For example, the following dependency would always download the latest 1.2 development JAR of spring:
<dependency>
  <groupId>springframework</groupId>
  <artifactId>spring</artifactId>
  <version>1.2-SNAPSHOT</version>
</dependency>
When you use SNAPSHOT dependencies you are telling Maven to use the latest version in the remote repository. This will come in handy when you are using the Multiproject plug-in, or when you are depending on an artifact still in development, as will often be the case if you're working on a team consisting of more than a few developers. You will be using SNAPSHOT dependencies when your project depends on the latest development or unreleased version of a particular component. SNAPSHOT dependencies should be reserved for development purposes, and, as a rule, you should never release a project that depends on a SNAPSHOT dependency.
Maven 2 increases the configurability of the SNAPSHOT dependency mechanism. The next release will allow you to specify how often Maven checks for an updated SNAPSHOT release.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Performing an Offline Build
If you need to use Maven in a disconnected situation, you'll need to know how to convince Maven not to check for the presence of an up-to-date SNAPSHOT dependency. This lab will show you how to perform an offline build using Maven.
The process is simple: just use the -o command-line option. For example, if you do not have a network connection, but would like to execute the test goal, run maven -o test. Maven will then execute the test goal without checking for dependencies. If your project does not depend on SNAPSHOT builds, you should be able to disconnect your environment without having to add the -o flag. If you do rely on SNAPSHOT builds, you will need to use the -o flag, as Maven will attempt to check for the presence of a newer SNAPSHOT every time it executes a goal. In this case, the project will not build successfully without the use of the -o flag.
...performing an offline build if I haven't downloaded any artifacts?
Of course, this won't work. For an offline build to work you must already have the required dependencies in your local repository. The easiest way to get Maven to download dependencies for a project is to run a simple "noop" goal present in every Maven project—for instance, build:start. This goal is executed before any other goal and does not perform any action. If you run build:start, Maven will grab any dependency referenced from the project.xml file.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Using the Maven Console
If you are repeatedly running Maven from the command line, you can save yourself some time by using the Maven Console. The Maven Console provides a "shell" where you can type in the name of a goal for Maven to execute. By using the Maven Console, you can avoid waiting for the Java Virtual Machine (JVM) to start up every time you want to run a Maven goal.
The Maven Console is a plug-in, and you can start it by entering maven console at the command prompt. This should produce the following output:
_ _  _ _
|  \/  |_ _ _Apache_ _ _ _ _
| |\/| / _` \ V / -_) ' \  ~ intelligent projects ~
|_|  |_\_ _,_|\_/\_ _ _|_||_|  v. 1.0.2
  
The following commands are available:
  
    list - list all available goals
    help - this message
    <goalname> - attain a goal
    quit - quits the console
  
test-application 1.0 >
At this point, you can execute any goal you could execute from the command line. Go ahead and try it; type java:compile. Maven will execute the java:compile goal and return you to the prompt to wait for another goal. To run two goals in sequence, you may enter them at the prompt, separated by a space—for example, clean test. This is known as "goal chaining" and it is a way for you to specify a series of goals you want Maven to obtain, in order. To exit the Maven Console, type quit, and to see a list of available goals, type list.
Maven executed the java:compile goal very quickly in the Maven Console, didn't it? When you use the Maven Console you are executing a goal in an existing JVM. When you run Maven from the command line, you have to wait for the JVM to start up every time you want to run a goal. If you are not convinced of the performance improvement, try it for yourself. Run the java:compile goal from the command line 10 times in a row, and then run the same java:compile goal from the Maven Console 10 times. Take note of the time difference, and you will see that the JVM startup time begins to increase. Use the Maven Console if you find yourself frequently running Maven goals, as it saves time by starting a JVM once.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Generating an Eclipse Project
I'll bet that you want to start working in an IDE. Maven comes with plug-ins for Eclipse, IntelliJ IDEA, JBuilder, JDeveloper, and Emacs. While Maven integrates well with all of these tools, this lab focuses on its integration with Eclipse, a popular open source IDE.
The process is simple; just execute the eclipse plug-in:
C:\dev\mavenbook\code\genapp\test-application> maven eclipse
  
build:start:
  
eclipse:generate-project:
    [echo] Creating C:\dev\mavenbook\code\genapp\test-application/.project ...
  
eclipse:generate-classpath:
    [echo] Creating C:\dev\mavenbook\code\genapp\test-application/.classpath ...
    [echo] Contains JUnit tests
    [echo] Setting compile of src/test to target/test-classes
Plugin 'cactus-maven' in project 'Test Application' is not available
    [echo] Setting default output directory to target/classes
  
eclipse:
    [echo] Now refresh your project in Eclipse (right click on the project and select 
"Refresh")
BUILD SUCCESSFUL
Total time: 2 seconds
Maven creates the two files which identify this project as an Eclipse project: .project and .classpath. In Eclipse, you can then import this project by following these steps:
  1. Start Eclipse.
  2. Select File Import... from the menu.
  3. Select Existing Project into Workspace and click the Next button.
  4. Select the C:\dev\mavenbook\code\genapp\test-application directory in the Import dialog, and click the Finish button.
You will then need to perform one more step to point Eclipse at the local Maven repository. Eclipse uses a variable named MAVEN_REPO to point to the local Maven repository. You can set MAVEN_REPO using Maven, by executing the following at the command line:
maven -Dmaven.eclipse.workspace=c:\eclipse\workspace eclipse:add-maven-repo
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Using the Eclipse Maven Plug-in
Yes, there is a quality Maven plug-in you can use in Eclipse. It supports a number of interesting features, such as the ability to edit project.xml files, support for Maven customization, and a Maven repository browser, among other features.
Mevenide (http://mevenide.codehaus.org/mevenide-ui-eclipse/update/index.html) is an Eclipse plug-in which allows you to use Maven from within Eclipse. You can download it from an Eclipse Update site by following these directions:
  1. Start Eclipse.
  2. Select Help Software Updates Find and Install from the menu.
  3. In the Install/Update dialog, select "Search for new feature to install," and click Next.
  4. In the Install dialog, click New Remote Site.
  5. In the New Update Site dialog, type Mevenide into the Name field, and the location of the Eclipse Update site into the URL field. The Eclipse Update site for Mevenide is http://mevenide.codehaus.org/release/eclipse/update/site.xml.
  6. When the word Mevenide appears in the Install dialog, select both of the children, Maven and Mevenide, and click Next.
  7. Once Maven and Mevenide are downloaded and installed, restart Eclipse.
The first thing you'll notice is that Mevenide has marked every project.xml file with a green icon. To open project.xml in the Project Object Model Editor, right-click any project.xml file and select Open With... Project Object Model Editor. This editor will display the panel shown in Figure 1-3.
Figure 1-3: Overview panel of Mevenide's Project Object Model Editor
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Generating an Ant Build File
There are times when you will want to build using Apache Ant. Maybe your project is using an automated process which relies on Ant, or maybe you have some team members who are not yet comfortable making the transition to Maven and who wish to continue using Ant. Since many IDEs already support projects with Ant build files, you can use Maven to generate a build.xml file so that your project can be built using Apache Ant.
Run the Ant plug-in. Running maven ant will create a build.xml file which contains targets to gather dependencies, build, and test your application. Take a look at the output of running the default jar target:
C:\dev\mavenbook\code\genapp\test-application>ant
Buildfile: build.xml
  
init:
    [mkdir] Created dir: C:\dev\mavenbook\code\genapp\target\lib
  
get-deps:
      [get] Getting: http://www.ibiblio.org/maven/springframework/jars/spring-core-1.1.4.jar
      [get] Getting: http://www.ibiblio.org/maven/springframework/jars/spring-web-1.1.4.jar
  
compile:
     [copy] Copying 1 file to C:\dev\mavenbook\code\genapp\target\classes
  
junit-present:
     [echo]  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  = WARNING =  =  =  = =  
=  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =
     [echo] Junit isn't present in your ${ANT_HOME}/lib directory. Tests not executed.
     [echo] =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  
=  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  
  
compile-tests:
  
internal-test:
  
test:
  
jar:
      [jar] Building jar: C:\dev\mavenbook\code\genapp\test-application\target\
test-application-1.0.jar
  
BUILD SUCCESSFUL
Total time: 2 seconds
You may have noticed that there is a problem, and it is an illustrative problem. Apache Ant does not automatically manage the dependencies for optional Ant tasks. If you want to run the JUnit tests, you will need to copy the junit-3.8.1.jar file from the local Maven repository to ${ANT_HOME}/lib. This build file contains a get-deps target which executes the Ant
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Migrating a Project from Ant to Maven
A fair number of projects use Ant as a build system, and you will want to migrate to Maven.
Start from scratch. Create a default Maven template, and then move your code to the proper directories. Do not try to fit Maven to your own project's directories and build locations. Maven is more than a build tool; it is a standard way to think about project layout and management. If you attempt to fit Maven to your project's idea of a build, you'll end up using Maven as it was never intended. If your project consists of a complex build.xml file which produces a number of different deliverables, you will need to "componentize" your project and follow the model for multiprojects described in Chapter 3. You will also need to start moving your project's directory structure toward the standard Maven project directory structure presented throughout this book. In other words, don't try to "shoehorn" Maven onto your project.
If you are interested in migrating to Ant, but you don't have time to stop development, you can always use Maven to call your existing Ant targets. If you do this, you'll miss out on a large part of the benefit of using Maven, but it is a possibility. For more information, see the informative "Migrating from Ant" document located at http://maven.apache.org/using/migrating.html.
...flexibility and choice?
Flexibility and choice are part of the original problem. We promise that Maven will change the way you approach building and maintaining your project, but it is important to use Maven as Maven was intended to be used. What are the differences between Maven and Ant? Where Ant offers building blocks in the form of reusable tasks such as copy, move, delete, and junit, Maven offers reusable build processes. Maven is a "build container" which allows you to reuse build processes over a series of projects. Take unit testing as just one example. With Ant, you would perform a JUnit test by including the following in your project's
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Generating Project Documentation
If you are developing a Java application or library, you might want to generate JavaDoc.
Simply execute the javadoc goal and Maven will generate project documentation. Here is the output of the execution of the javadoc goal:
C:\dev\mavenbook\code\genapp\test-application>maven javadoc
 _ _  _ _
|  \/  |_ _ _Apache_ _ _ _ _
| |\/| / _` \ V / -_) ' \  ~ intelligent projects ~
|_|  |_\_ _,_|\_/\_ _ _|_||_|  v. 1.0.2
  
build:start:
  
xdoc:init:
  
maven-javadoc-plugin:report:
    [mkdir] Created dir: C:\dev\mavenbook\code\genapp\test-application\target\
javadoc\src
    [javadoc] Generating Javadoc
    [javadoc] Javadoc execution
    [javadoc] Loading source files for package mdn.testapp...
    [javadoc] Constructing Javadoc information...
    [javadoc] Standard Doclet version 1.5.0_01
    [javadoc] Building tree for all the packages and classes...
    [javadoc] Generating C:\dev\mavenbook\code\genapp\test-application\target\docs\apidocs\
constant-values.html...
    [javadoc] Copying file C:\Documents and Settings\tobrien\.maven\cache\
maven-javadoc-plugin-1.7\plugin-resources\stylesheet.css to file C:\dev\mavenbook\code\
genapp\test-application\target\docs\apidocs\stylesheet.css...
    [javadoc] Building index for all the packages and classes...
    [javadoc] Building index for all classes...
    [delete] Deleting directory C:\dev\mavenbook\code\genapp\test-application\target\
javadoc\src
BUILD SUCCESSFUL
Total time: 7 seconds
Once this goal has been executed, JavaDoc is available in test-application/target/docs/apidocs.
Once again, Maven did all of the heavy lifting. You wanted JavaDoc, you told Maven to generate JavaDoc, end of story. Note that you didn't need to tell Maven anything about the project; it just "knew" what to do. Much of Maven is this straightforward; after you tell Maven about your project there isn't much more you need to do. It handles the details.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Telling Maven About Your Team
Maven is a great collaboration tool which you can use to generate developer activity reports, as well as lists of project contributors and mailing lists.
Most projects have a mailing list which is used to discuss architecture and implementation. And, from one perspective, projects such as Tomcat, Maven, and Ant are nothing more than a community of developers who share a subscription to the same mailing list. Mailing lists are not just for open source projects; many organizations are starting to use the same collaborative model used in open, public development. Because mailing lists are a pivotal part of collaboration, Maven provides a way for you to specify project mailing lists in project.xml. The following excerpt from project.xml adds a mailingLists element:
<mailingLists>
  <mailingList>
    <name>Maven User List</name>
    <subscribe>users-subscribe@maven.apache.org</subscribe>
    <unsubscribe>users-unsubscribe@maven.apache.org</unsubscribe>
    <archive>http://marc.theaimsgroup.com/?l=turbine-maven-user</archive>
  </mailingList>
  <mailingList>
    <name>Maven Developer List</name>
    <subscribe>dev-subscribe@maven.apache.org</subscribe>
    <unsubscribe>dev-unsubscribe@maven.apache.org</unsubscribe>
    <archive>http://marc.theaimsgroup.com/?l=turbine-maven-dev</archive>
  </mailingList>
</mailingLists>
There are two types of team members in Maven projects: contributors and developers. While the definition may change for your project, contributors are usually members of an open source community who have contributed patches or documents, and developers are core members of a project. In the ASF, contributors and committers can both contribute to a project, but contributors have neither write access to the source repository nor a vote in major project decisions. The following excerpt from project.xml adds a contributor and a developer element to project.xml:
<developers>
  <developer>
    <name>Vincent Massol</name>
    <id>vmassol</id>
    <email>vmassol@apache.org</email>
    <organization>Apache Software Foundation</organization>
    <roles>
      <role>Author</role>
      <role>Developer</role>
    </roles>
    <url>http://www.massol.net</url>
    <timezone>+1</timezone>
  </developer>
</developers>
<contributors>
  <contributor>
    <name>Tim OBrien</name>
    <email>tobrien@apache.org</email>
    <organization>Apache Software Foundation</organization>
    <roles>
      <role>Author</role>
      <role>Developer</role>
    </roles>
    <url>http://www.oreillynet.com/pub/au/1738</url>
    <timezone>-6</timezone>
  </contributor>
</contributors>
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Pointing Maven at Source Control
Do you use source control? Tell Maven about it, and you'll be able to generate some interesting reports described later in this book. Once you have associated your project with a source code repository, you will be able to use the Maven Source Control Management (SCM) plug-in which provides goals for updating and releasing from a version control system such as CVS or Subversion.
You need to add a repository element to your project's project.xml. The following repository element is from the Apache Struts project, and it points to the Subversion repository available at http://svn.apache.org/repos/asf/struts/core/trunk:
<repository>
  <connection>
    scm:svn:http://svn.apache.org/repos/asf/struts/core/trunk
  </connection>
  <developerConnection>
    scm:svn:https://svn.apache.org/repos/asf/struts/core/trunk
  </developerConnection>
  <url>http://svn.apache.org/repos/asf/struts/core/trunk</url>
</repository>
The connection element tells Maven about the read-only location of the SCM. scm identifies this URL as being an SCM location, svn tells Maven that this URL will be for a Subversion repository, and the final section of the URL is the location to the project's trunk. You may also specify the developerConnection; you use this element when you need to segment your audience into people without write access to source code, and people with write access.
The url element supplies a URL that can be used to browse the repository. In the case of Struts, they have elected to point to the Subversion repository itself, as it can be browsed with a regular web browser. The Struts team could also elect to point to the ViewCVS instance configured to point to the ASF Subversion repository, which can be found at the following URL: http://cvs.apache.org/viewcvs.cgi/struts/core/trunk/?root=Apache-SVN.
When you point a project.xml file at a particular source control system, you can also specify the different versions and branches of a particular project. The following XML shows a reduced version of the
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Creating a Project Web Site
Maven can create a project web page, with metrics and information about a project.
To create a Maven project web site, use the Site plug-in by running the following Maven goal:
C:\dev\mavenbook\code\genapp\test-application> maven site
            
Running the Site plug-in will create the project's web site in the default site output directory: test-application/target/docs/index.html. If you load this HTML, you will see a site with a distinctive Maven look and feel. Figure 1-5 shows a sample of a lightly customized Maven web site complete with a custom organization logo and project logo. Instead of showing you a contrived web site, you can see the site of a project currently using Maven as a build system—Jaxen.
Figure 1-5: Sample Maven project web site
Most Maven sites have a Project Documentation navigation section which provides links to information common to all Maven projects. Project Info contains information about the project, a list of the project mailing lists, and information about source control and issue tracking (you'll discover all this in Section 4.1). Content for the generated Maven web site is developed by creating and modifying XML markup in the xdocs directory. In Figure 1-5, the project contains five project-specific documents: Overview, FAQ, Releases, CVS Access, and Status. These documents are included in the left navigation bar because they are included in the xdocs/navigation.xml file. The xdocs directory is where Maven stores project-specific documentation in an XML XDoc format. Here are the contents of the navigation.xml document for Jaxen:
<?xml version="1.0" encoding="ISO-8859-1"?>
  
<project name="jaxen" repository="jaxen" href="http://jaxen.org">
  
  <title>jaxen: universal java xpath engine</title>
  
  <body>
    <links>
      <item name="The Werken Company" href="http://www.werken.com/"/>
    </links>
    <menu name="jaxen">
      <item name="Overview" href="/index.html"/>
      <item name="FAQ" href="/faq.html"/>
      <item name="Releases" href="/releases.html"/>
      <item name="CVS Access" href="/cvs-usage.html"/>
      <item name="Status" href="/status.html"/>
     </menu>
   </body>
  
</project>
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Customizing Site Reports
Site generation creates a number of useful reports, but depending on your style, you may want to deactivate some of these reports.
To change the reports generated by Maven's site generation, alter the contents of the reports element in project.xml. Here is a reports element with several available reports activated:
<reports>
  <report>maven-changelog-plugin</report>
  <report>maven-changes-plugin</report>
  <report>maven-checkstyle-plugin</report>
  <report>maven-clover-plugin</report>
  <report>maven-cruisecontrol-plugin</report>
  <report>maven-developer-activity-plugin</report>
  <report>maven-faq-plugin</report>
  <report>maven-file-activity-plugin</report>
  <report>maven-license-plugin</report>
  <report>maven-linkcheck-plugin</report>
  <report>maven-javadoc-plugin</report>
  <report>maven-jdepend-plugin</report>
  <report>maven-jira-plugin</report>
  <report>maven-junit-report-plugin</report>
  <report>maven-jxr-plugin</report>
  <report>maven-pmd-plugin</report>
  <report>maven-simian-plugin</report>
  <report>maven-tasklist-plugin</report>
</reports>
To exclude a report from Maven's site generation, just remove the report's plug-in element from the reports element. A Maven project that does not specify the reports element generates a set of default reports: jdepend, Checkstyle, changes, changelog, developer-activity, file-activity, license, javadoc, jxr, junit, linkcheck, and tasklist. When you add a reports element to your project's project.xml file, you must list all reports you wish to have generated.
The reports element lists all these fancy reports, but you probably want to know what all of these reports provide. Table 1-1 provides a brief description of some of these reports.
Table 1-1: Report plug-ins
Report plug-in
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 2: Customizing Maven
In Chapter 1 you worked with the project.xml file, which describes the project, organization, team, location of source files, and other information Maven uses to build a project. You saw how to list available goals, and how easy it is to start using Maven. Often you'll need to customize the build process Maven uses to suit your own needs; for example, you may need to copy a JAR file to another directory, or you may want to write your own goal. This chapter focuses on Jelly and the maven.xml file.
While Maven 1 plug-ins are written in Jelly, Maven 2 moves away from this XML scripting language in favor of plug-ins written in Java (plain old Java). So, don't get too enamored with Jelly. Maven 2 is moving away from Jelly for a number of reasons, one of them being performance. As a consequence, always try to reduce the size of your maven.xml file and reuse the existing plug-ins as much as possible. This will save you countless hours when you switch to Maven 2 in the future. After telling you this, why should you still read this chapter? Because you need to know Jelly for Maven 1, and Maven 2 will still support it in some fashion, but plug-in developers will be encouraged to write plug-ins in Java. Maven 2 may also include integration with other Java scripting frameworks, such as Groovy and Marmalade. This chapter isn't just about Jelly, and many of the concepts presented in this chapter will remain relevant.
The sample project, called Weather, which is used in this lab, is available from the http://www.mavenbook.org web site. You can also check out the Weather project from a Subversion repository at http://www.mavenbook.org/svn/mdn/code/.
All your Java buddies are using the latest and greatest version of some fancy Maven plug-in, and you are starting to feel left out and ignored. How did they get the plug-in? And once they obtained it, how did they install it? To demonstrate the process of installing a plug-in, install the Apache Axis plug-in in your Maven installation.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Installing a Plug-in from a Remote Repository
All your Java buddies are using the latest and greatest version of some fancy Maven plug-in, and you are starting to feel left out and ignored. How did they get the plug-in? And once they obtained it, how did they install it? To demonstrate the process of installing a plug-in, install the Apache Axis plug-in in your Maven installation.
The first thing you need to know is the location of the Maven remote repository where the plug-in you wish to install is located. In the case of the Apache Axis plug-in, the repository is at http://maven-plugins.sourceforge.net/maven/. However, this repository is synced every few hours to the ibiblio repository at http://www.ibiblio.org/maven/. The ibiblio repository is the default Maven remote repository and the one that will be used if you don't tell Maven otherwise. Should you still wish to add the remote repository to your Maven configuration, you should modify your build.properties file (or project.properties file if you want to share the settings with others) and include the following property:
maven.repo.remote=http://www.ibiblio.org,http://maven-plugins.sf.net/maven
However, as this repository is synced with ibiblio, it's not necessary for installing the Axis plug-in. At the time of this writing, the latest version of the Axis plug-in (as can be seen at http://www.ibiblio.org/maven/maven-plugins/plugins/) is version 0.7. To install it, you need to use the plugin:download goal of the Plugin plug-in, passing it some properties, as shown shortly.
In the same manner you define a groupId, an artifactId, and a version when you create a dependency in your project.xml file, you need to pass the same properties to the Plugin plug-in so that it knows the exact location of the plug-in you want to download and install. Issue the following command from any directory to install version 0.7 of the Axis plug-in:
C:\>maven plugin:download -DgroupId=maven-plugins ^
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Customizing Plug-in Behavior
In this lab, you'll be working with a web service maintained by the U.S. government's National Oceanic and Atmospheric Administration (NOAA). The U.S. government recently decided that weather feeds should be made available to the general public at no charge, so now it provides a forecast server at http://weather.gov/xml/. You are going to use the Maven Axis plug-in to generate classes which will retrieve a forecast from this web service. To do this, you will need to customize the behavior of the Axis plug-in.
If you've successfully installed the Axis plug-in, maven -P axis should list the goals available in the plug-in; one of them should be axis:wsdl2java. You are going to use this goal to generate a client library from the Web Service Description Language (WSDL) for the weather web service.
You can find the WSDL for the NOAA forecast service at http://weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl. A WSDL document is an XML document which completely describes the methods available in a SOAP service. The Axis plug-in is going to use this XML document to create a client library. For the purposes of this lab, this WSDL document is stored in weather/src/wsdl/weather.wsdl. The Axis plug-in will generate Java source files for all WSDL documents found in this directory.