Setting Up and Integrating Maven
with Eclipse

Russell Bateman, May 2008

This is me trying to figure out how to use Maven with Eclipse. The best documentation I have found is at http://www.sonatype.com/book/. This page won't try to duplicate that content, but document my progress toward getting a working Maven project for use with Eclipse Web Tool Project (WTP), specifically, a Dynamic Web Project. Thus, these are working notes with initially false ideas that will be corrected as I progress. If they are of any value to you, be my guest and use them. If you feel inclined to draw my attention to something, feel free to contact me at russ@windofkeltia.com.

Maven is the queen of build systems. It blows the doors off make and ant. Maven is how you

  1. create a blank, ready-to-write dynamic web or other project (for Eclipse or any other IDE)
  2. maintain and automatically download the latest foreign dependencies for said project*
  3. build (automatically) said project
  4. install said project
  5. produce distros (WAR files, etc.) for said project

* If your project depends on some third-party framework, this is cool because you just figure out where to get it, tell Maven, and Maven will always ensure you have the latest version thereof (if you want) or, if you move your project development to another computer (or you're cooperating with other team members who have their own workstations), Maven will ensure all dependencies of this sort anywhere.

It is not only THE solution to automated builds of projects that, being done in an IDE, would normally defy automated configuration management, but also a great stub generator creating your whole project source and test tree automatically. It does this based on its own rules, but if you like to name your stuff differently, you can configure that. With ant, you had to write the whole thing from scratch without which your project directories and build rules didn't exist. If you like, you can just mindlessly let Maven decide your project directory structure and dependencies. There are plug-ins for all sorts of IDE and development environments that people have put together.


Table of Contents


Setting Up Maven

Here's the question I finally gave up and asked of the news group and the answer I received (in red).

	I'm looking for help getting going with Maven and Eclipse. I've read lots,
	but have been unable to synthesis what I've read into a practical, working
	procedure. I'm looking for some direction (URLs or other suggestions).

	Where am I?

	I have downloaded Maven and run it successfully to create the sample myapp
	Hello World project.  I have found and downloaded Maven plugins for Eclipse,
	though I haven't figured out where to put them yet. For now, I've tucked them
	away in a folder parallel to my Tomcat installation.

	   C:\Program Files\Apache Software
	   Foundation\apache-maven-2.0.9\plugins> dir

	   Directory of C:\Program Files\Apache Software Foundation\apache-maven-2.0.9\plugins

	   04/30/2008  07:38 PM    <DIR>      .
	   04/30/2008  07:38 PM    <DIR>      ..
	   04/30/2008  07:37 PM       409,126 maven-eclipse-plugin-2.5.1-javadoc.jar
	   04/30/2008  07:37 PM       181,400 maven-eclipse-plugin-2.5.1.jar
	   04/30/2008  07:38 PM         7,174 maven-eclipse-plugin-2.5.1.pom
	                  3 File(s)   597,700 bytes
	                  2 Dir(s)  95,256,113,152 bytes free*

	I have used Eclipse's Sofware Update/Find and Install facility to fetch down
	a plugin for Eclipse. These would apparently be the famous "Q" plugins for use
	FROM Eclipse while the previous ones are those used FROM Maven. Or so my
	reading encourages me to believe.

	   C:\tutorial\eclipse\plugins> dir *maven*

	   Directory of C:\tutorial\eclipse\plugins

	   04/30/2008  09:04 PM  2,047,318 org.apache.maven.embedder_2.1.0.627670.jar
	   04/30/2008  09:04 PM     41,565 org.apache.maven.shared.dependency.tree_1.1.0.v200802050958.jar
	   04/30/2008  09:04 PM    426,398 org.devzuz.q.maven.core_0.6.0.200804131445.jar
	   04/30/2008  09:04 PM     63,497 org.devzuz.q.maven.dependency.analysis_0.6.0.200804131445.jar
	   04/30/2008  09:04 PM     17,652 org.devzuz.q.maven.dependencyviewer_0.6.0.200804131446.jar
	   04/30/2008  09:04 PM     48,308 org.devzuz.q.maven.jdt.core_0.6.0.200804131445.jar
	   04/30/2008  09:04 PM     54,760 org.devzuz.q.maven.jdt.ui_0.6.0.200804131445.jar
	   04/30/2008  09:04 PM    665,387 org.devzuz.q.maven.ui_0.6.0.200804131445.jar
	   04/30/2008  09:04 PM    148,246 org.devzuz.q.maven.wizard_0.6.0.200804131445.jar
	   04/30/2008  09:04 PM      7,834 org.devzuz.q.maven.wtp.core_0.6.0.200804131446.jar
	                 10 File(s)      3,520,965 bytes
	                  0 Dir(s)  95,256,096,768 bytes free*

	And I've tried running "mvn eclipse" realizing that that is way too naive
	as a starting point. I'm guessing that to create a Dynamic Web Project under
	Maven control for use in Eclipse, I have to create a BLANK PROJECT on the
	command line in Maven, but there's something about the Eclipse workbench
	plugin that will give me all the right directories and a fully WTP-armed POM.
	Then, I can copy (?) this blank somewhere and use it ever after (or just use
	Maven to create a new blank every time I need one)?

	> Look at archetypes.
	> (Hint: http://docs.codehaus.org/display/M2ECLIPSE/New+and+Noteworthy)
	> 
	> More importantly, have a look at:
	> http://www.sonatype.com/book/
	> 
	> Also, use this:
	> http://m2eclipse.codehaus.org/

	The questions I'm looking to answer are:

	   - How do I invoke the Maven plugin inside Eclipse to "tell" Maven to
	   create me a "fully WTP-armed" POM?

	   > mvn archetype:create ^
	   >     -DarchetypeGroupId=<group id of the appropriate archetype> ^
	   >     -DarchetypeArtifactId=<aart. id of the appropriate archetype> ^
	   >     -DarchetypeVersion=1.0-SNAPSHOT ^
	   >     -DgroupId=<Project Group Id> ^
	   >     -DartifactId=<Project Name>
	   > cd <Project Name>
	   > mvn eclipse:eclipse
	   > 
	   > That will get you started.
	   > 
	   > We've set up a parent POM that has this section in it:
	   > 
	   >  <build>
	   >    <pluginManagement>
	   >      <plugins>
	   >        <plugin>
	   >          <artifactId> maven-eclipse-plugin            </artifactId>
	   >          <version>    ${maven-eclipse-plugin.version} </version>
	   >          <configuration>
	   >            <downloadSources>  ${ide.download.sources} </downloadSources>
	   >            <downloadJavadocs> ${ide.download.javadoc} </downloadJavadocs>
	   >            <wtpversion>       ${eclipse.wtp.version}  </wtpversion>
	   >          </configuration>
	   >        </plugin>
	   >      </plugins>
	   >    </pluginManagement>
	   >  </build>
	   > 
	   >  <properties>
	   >    <maven-eclipse-plugin.version> 2.5.1 </maven-eclipse-plugin.version>
	   > 
	   >    <ide.download.sources> true  </ide.download.sources>
	   >    <ide.download.javadoc> false </ide.download.javadoc>
	   > 
	   >    <eclipse.wtp.version>  1.5   </eclipse.wtp.version>
	   >  </properties>

	   - What does it leave lying around that tells me this has succeeded?

	   - What Maven command do I use on the Windoz/DOS command line to
	   create this mythical project with Eclipse .classpath/.metadata/etc.
	   stuff in it?

	   > That is what the mvn eclipse:eclipse tasks does (by its very definition)

	   - How do I import the new project into Eclipse so I can get developing?

	   > Import it like any other (existing) eclipse project...

	   - Will the full-octane, WTP-armed POM and project hierarchy come
	   with /faces-config.xml/, /web.xml/, etc.

	   > Depends on what archetypes you've used/parent poms you've inherited from.

	I have heard that this is possible and that Maven is going to do all these
	cools things for me, but after hours of research reading link after followed
	link, I've only stumbled on more or less how to install and nothing
	about how to use. I'm not looking for anyone to do the work for me, but
	a list of URLs or some pointers would be greatly helpful.

	> Not that far ahead of you myself, and yes it is painfully difficult...

Learning from the Sonatype document...

Chapter 3 is the first example. Download the zipped sample code from http://www.sonatype.com/book/mvn-examples-1.0.zip. This link is found along with one for a tarball of the same sample code (for use on Unix/Linux) at http://www.sonatype.com/book/#.

The first command must be executed from mvn-examples-1.0 and not from deeper (like ch03 or ch03/simple). Errors occur if you do it from anywhere else.

	C:\Documents and Settings\russ\Desktop\mvn-examples-1.0> mvn archetype:create \
			-DgroupId=com.conatype.maven.ch03 \
			-DartifactId=simple \
			-DpackageName=com.sonatype.maven
	[INFO] Scanning for projects...
	[INFO] Searching repository for plugin with prefix: 'archetype'.
	[INFO] ------------------------------------------------------------------------
	[INFO] Building Maven Default Project
	[INFO]    task-segment: [archetype:create] (aggregator-style)
	[INFO] ------------------------------------------------------------------------
	[INFO] Setting property: classpath.resource.loader.class => \
			'org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader'.
	[INFO] Setting property: velocimacro.messages.on => 'false'.
	[INFO] Setting property: resource.loader => 'classpath'.
	[INFO] Setting property: resource.manager.logwhenfound => 'false'.
	[INFO] [archetype:create]
	[WARNING] This goal is deprecated. Please use mvn archetype:generate instead
	[INFO] ----------------------------------------------------------------------------
	[INFO] Using following parameters for creating OldArchetype: maven-archetype-quickstart:RELEASE
	[INFO] ----------------------------------------------------------------------------
	[INFO] Parameter: groupId, Value: com.conatype.maven.ch03
	[INFO] Parameter: packageName, Value: com.sonatype.maven
	[INFO] Parameter: package, Value: com.sonatype.maven
	[INFO] Parameter: artifactId, Value: simple
	[INFO] Parameter: basedir, Value: C:\Documents and Settings\russ\Desktop\mvn-examples-1.0
	[INFO] Parameter: version, Value: 1.0-SNAPSHOT
	[INFO] ********************* End of debug info from resources from generated POM ***********************
	[INFO] OldArchetype created in dir: C:\Documents and Settings\russ\Desktop\mvn-examples-1.0\simple
	[INFO] ------------------------------------------------------------------------
	[INFO] BUILD SUCCESSFUL
	[INFO] ------------------------------------------------------------------------
	[INFO] Total time: 3 seconds
	[INFO] Finished at: Sat May 03 22:13:28 MDT 2008
	[INFO] Final Memory: 8M/254M
	[INFO] ------------------------------------------------------------------------

An archetype is “an original model or type after which other similar things are patterned; a prototype.” It's an archetype I'm looking for to create my Eclipse WTP project with JSF and everything in place. for importing into Eclipse.

So, one of the salient differences between Maven and ant is that Maven will create things and generally work independently of whether you specify every last detail of your project. This means that it will choose to supply things, even source code blanks, if you do not instruct it specifically. With ant, it won't do anything unless you tell it to do so.

	C:\Documents and Settings\russ\Desktop\mvn-examples-1.0\ch03> tree
	Folder PATH listing
	Volume serial number is 0006EEA4 B0CE:6693
	C:.
	+---simple             [project base directory: -DartifactId=simple]
	    +---src
	        +---main       [project source code and resources—just how Maven does it unless you change something]
	        ¦   +---java
	        ¦       +---com
	        ¦           +---sonatype
	        ¦               +---maven
	        ¦                   +---App.java     [generated by Maven!]
	        +---test
	            +---java
	                +---com
	                    +---sonatype
	                        +---maven
	                            +---AppTest.java [generated by Maven!]

The Java source code files generated by Maven demonstrate its stubbing power: if you don't tell it what to do, it will take a guess, which is usually a stub, and your attention is drawn to these files it has guessed at which gives you a clue as to what you must do: fill in the blank by changing the name of the file, its contents, filling in the code, etc. This is freakin' cool (to adopt the current vernacular of the shop I work in).

Building and packaging the resulting application...

Here's where you change your working directory to ch03/simple where the pom.xml, the magic Maven file of heavenly holiness and governance, resides.

	C:\Documents and Settings\russ\Desktop\mvn-examples-1.0> cd ch03\simple

In that directory, you can execute commands to build and package the application. (This is no difference from the document, chapter 3, but I want to show it here for quick reference.)

	C:\Documents and Settings\russ\Desktop\mvn-examples-1.0\ch03\simple> mvn install
	[INFO] Scanning for projects...
	[INFO] ------------------------------------------------------------------------
	[INFO] Building Chapter 3 Simple Project Example
	[INFO]    task-segment: [install]
	[INFO] ------------------------------------------------------------------------
	Downloading: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-install-plugin/2.2/maven-install-plugin-2.2.pom
	2K downloaded
	Downloading: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-install-plugin/2.2/maven-install-plugin-2.2.jar
	15K downloaded
	[INFO] [resources:resources]
	[INFO] Using default encoding to copy filtered resources.
	[INFO] [compiler:compile]
	[INFO] Compiling 1 source file to C:\Documents and Settings\russ\Desktop\mvn-examples-1.0\ch03\simple\target\classes
	[INFO] [resources:testResources]
	[INFO] Using default encoding to copy filtered resources.
	[INFO] [compiler:testCompile]
	[INFO] Compiling 1 source file to C:\Documents and Settings\russ\Desktop\mvn-examples-1.0\ch03\simple\target\test-classes
	[INFO] [surefire:test]
	[INFO] Surefire report directory: C:\Documents and Settings\russ\Desktop\mvn-examples-1.0\ch03\simple\target\surefire-reports

	-------------------------------------------------------
	 T E S T S
	-------------------------------------------------------
	Running com.sonatype.maven.AppTest
	Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.062 sec

	Results :

	Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

	[INFO] [jar:jar]
	[INFO] Building jar: C:\Documents and Settings\russ\Desktop\mvn-examples-1.0\ch03\simple\target\simple-1.0-SNAPSHOT.jar
	Downloading: http://repo1.maven.org/maven2/org/apache/maven/maven-project/2.0.6/maven-project-2.0.6.pom
	2K downloaded
	Downloading: http://repo1.maven.org/maven2/org/apache/maven/maven-settings/2.0.6/maven-settings-2.0.6.pom
	1K downloaded
	Downloading: http://repo1.maven.org/maven2/org/apache/maven/maven-model/2.0.6/maven-model-2.0.6.pom
	2K downloaded
	Downloading: http://repo1.maven.org/maven2/org/apache/maven/maven-profile/2.0.6/maven-profile-2.0.6.pom
	1K downloaded
	Downloading: http://repo1.maven.org/maven2/org/apache/maven/maven-artifact-manager/2.0.6/maven-artifact-manager-2.0.6.pom
	2K downloaded
	Downloading: http://repo1.maven.org/maven2/org/apache/maven/maven-repository-metadata/2.0.6/maven-repository-metadata-2.0.6.pom
	1K downloaded
	Downloading: http://repo1.maven.org/maven2/org/apache/maven/maven-artifact/2.0.6/maven-artifact-2.0.6.pom
	1K downloaded
	Downloading: http://repo1.maven.org/maven2/org/apache/maven/maven-plugin-registry/2.0.6/maven-plugin-registry-2.0.6.pom
	1K downloaded
	Downloading: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus-digest/1.0/plexus-digest-1.0.pom
	1K downloaded
	Downloading: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus-components/1.1.7/plexus-components-1.1.7.pom
	4K downloaded
	Downloading: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus-digest/1.0/plexus-digest-1.0.jar
	11K downloaded
	[INFO] [install:install]
	[INFO] Installing C:\Documents and Settings\russ\Desktop\mvn-examples-1.0\ch03\simple\target\simple-1.0-SNAPSHOT.jar to C:\Documents and Settings\russ\.m2\repository\com\sonatype\maven\ch03\simple\1.0-SNAPSHOT\simple-1.0-SNAPSHOT.jar
	[INFO] ------------------------------------------------------------------------
	[INFO] BUILD SUCCESSFUL
	[INFO] ------------------------------------------------------------------------
	[INFO] Total time: 10 seconds
	[INFO] Finished at: Sat May 03 22:53:12 MDT 2008
	[INFO] Final Memory: 13M/254M
	[INFO] ------------------------------------------------------------------------

All this downloading action noted is done when Maven recognizes it's missing something. It goes to get it. What has just happened is we've created, compiled, tested, packaged and installed the little application. Here we run it from the command line to prove it works:

	C:\Documents and Settings\russ\Desktop\mvn-examples-1.0\ch03\simple> java -cp \
			target/simple-1.0-SNAPSHOT.jar \
			com.sonatype.maven.App
	Hello World!

This is nothing short of freakin' amazing! However, the test subdirectory disappeared on me sometime during the last two commands. I'll have to figure out what happened there.



From here on, we'll more or less dispense with the long directory prefix from the DOS command line for convenience except where it is necessary to disambiguate the current working directory.



The POM file: most holy key to all wisdom, knowledge and behavior!

Following are the contents of the pom.xml file which I've formatted to show more easily what is going on:

	<project xmlns="http://maven.apache.org/POM/4.0.0"
	         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
	         http://maven.apache.org/maven-v4_0_0.xsd">
	  <modelVersion> 4.0.0                            </modelVersion>
	  <groupId>      com.sonatype.maven.ch03          </groupId>
	  <artifactId>   simple                           </artifactId>
	  <version>      1.0-SNAPSHOT                     </version>
	  <packaging>    jar                              </packaging>
	  <name>         Chapter 3 Simple Project Example </name>
	  <url>          http://sonatype.com/book         </url>
	  <dependencies>
	    <dependency>
	      <groupId>    junit </groupId>
	      <artifactId> junit </artifactId>
	      <version>    3.8.1 </version>
	      <scope>      test  </scope>
	    </dependency>
	  </dependencies>
	</project>

In addition to this file, which is project-specific, Maven works according to its own volumninous pom.xml which can be revealed thus:

	C:> mvn help:effective-pom
	(Lots of output...)

Maven Plug-ins and Goals

What are local repository, lifecycle, goals? (This table under construction.)

type ? command-line argument
plug-in goal Archetype plug-in mvn archtype:create
life-cycle phase ? mvn install

A Maven plug-in is a collection of one or more goals. A goal is a specific task executed by itself or in concert with other goals as part of a larger build. It is the “unit of work” in Maven. Examples include

Example

The compile goal of the Compiler plug-in defines a set of configuration parameters to allow you to specify the target JDK version and whether to use the compiler optimization. In the sample POM above, groupId and artifactId are parameters for the create goal of the Archetype plug-in and were specified using the command line (-D option). The packageName parameter was passed as com.sonatype.maven. Had it been omitted, it would not have been in the resulting POM file and, during the build, defaulted to com.sonatype.maven.ch03 (instead of com.sonatype.maven).

Goals define parameters that can define sensible default values. Maven is “convention over configuration.”

The convention for the create goal is to create a simple project named Quickstart. We overrode that using artifactId. The Archetype plug-in generates a minimal project shell containing a POM and a single class.

Life-cycle

The second command run (above) was mvn package—not a goal (unlike the first command), but a phase. The phase is a step in the “build life-cycle.” an ordered sequence of phases in the building of a project. Phase names are vaguely defined and their meanings likely deviate depending on the project. Phases are defined as steps that:

package, for instance, might mean to turn this project into a JAR or WAR. One series of phases in a build might consist of

Plug-in goals (as already discussed) generally attach to a life-cycle phase each goal executed in appropriate sequence to evolve the project toward the next phase.

Goal nomenclature

In designating a goal, it is typically given as the second half of a plug-in + goal tuple:

The goal of the jar plug-in is bound to the package phase, packaging the output directory into a JAR file. (This goal should not be confused with the character from StarWars episodes I, II and III.) Please see the illustrations in the document in the “Maven Lifecycle” section.

When Maven executes package, all phases up to package execute all goals bound to each phase. It would be possible to execute the whole series of plug-in goals in order (in our case, up to jar:jar); it is the same. It's like typing make final or make all back when you coded in C instead of make main.o, make thing.o, make -o myprogram one by one.

Each goal looks to the POM to find out what its filename or filenames are, what options to consider, etc. In the POM, we find Maven's coordinates, defined as the four XML elements

If asked for our project's coordinates, the response should be: com.sonatype.maven.ch03:simple:jar:1.0-SNAPSHOT. (Projects currently under development often use a special identifier, SNAPSHOT, to mark a version.) You can't have two projects with the same groupId, artifactId and version. Maven repositories are organized on this basis and one project can erect a dependency upon another using the Maven coordinates (including packaging).

Repositories

When Maven runs, amid the morass of flurried activity are notifications to the effect that a number of files are downloaded. These downloads are the latest release of the Resources plug-in as it triggers the resources:resource goal. Maven retrieves artifacts and plug-ins from a remote repository when they are needed. This is also the reason Maven is so small at installation: everything is up on the web and not in the installation.

A repository is a collection of project artifacts stored in a structure and format that are easily understood by Maven. Anything downloaded by Maven is cached on your local disk so it need not necessarily be downloaded again. On Windos XP, the local repository is (usually) C:\Documents and Settings\user\.m2\repository, on Vista, C:\Users\user\.m2\repository. On Unix/Linux, ~/.m2/repository.

The local repository is also used to share cross-dependencies between projects.

Dependency Management

Maven handles transient dependencies too. If you erect a dependence upon Hibernate, for example, it is not necessary to know what dozen libraries this dependency in its turn has on others. Maven will track them all down for you.

Let's think directly about JavaServer Faces for a moment. When you use this framework, you must create a library reference in Eclipse that consists at very least of

and, if those JARs ever change (are enhanced, upgraded, etc.), you must see to it that your Eclipse project is getting the latest. Maven can accomplish this for you. You can imagine a similar case for MySQL, the JDBC JAR, etc.

When you do a mvn install, Maven publishes a slightly different version of the local project pom.xml in the same directory as the project JAR file (under the repository, in our case,

Directory of C:\Documents and Settings\russ\.m2\repository\com\sonatype\maven\ch03\simple

05/03/2008  10:53 PM       319 maven-metadata-local.xml

This gives other, potential projects information about simple project—mostly just about its dependencies so that if Maven is building them and they depend on simple, the dependencies can be easily resolved.

The dependency isn't merely a known JAR file, but a POM which in turn may have other dependencies. And thereby these dependencies can be very transitory.

Reporting and Site Generation

On the other end of the spectrum of what Maven does and how it does it is the output: generation of documentation and reports. This occurs with the command mvn site.

Execute mvn site in the root of the simple project and examine the directories and files created under target. There's a whole set of web pages for your project.


Let's Get On with Maven and Eclipse...

Here are some links worth keeping:

In the first article (more a blog entry than anything else), after setting up my Dynamic Web Project, I could not at first follow step 7, “right click on pom.xml run maven install to download all jars and build the project.”

The “run maven install” instruction he refers to is in fact, Run As... followed by Maven install. Output goes to the Console window, bottom center of the Eclipse workbench, and it terminates in an error (of course). I'm guessing that when our author recommended creating a Java project, he meant the whole enchilada including source code. The reason I am tramping all over Maven country is precisely to learn how to use it to set up a blank JSF project with all the underlying dependencies met that I can then import into Eclipse.