Maven 2 (Part 1): Setting up a simple Apache Maven 2 project

Phillip Steffensen's picture

Java software development is often associated with repetitive tasks like building project's java classes, generating documentation and reporting. Doing this repetitive tasks manually costs a lot of time and tend to be error-prone. In addition to that it is extremely boring to do the same tasks again and again. These tasks should get automated, because they are often equal. To automate these tasks a build tool that could do this work is needed. Today, many java projects are using the Maven as a build tool to manage these objectives. The Maven project reached big popularity by making repetitive tasks automatable.

Another advantage when using Maven is that all dependencies referenced by the project are resolved automatically. This is extremely helpful for bigger java projects that use a huge set of dependencies. To explain how to use Maven and to help you to get into it we start a new tutorial-series about Maven 2 at united-coders.com. The initial part of this tutorial describes how to set up a Maven 2 project structure. Further parts of this tutorial-series will describe the main functionality of Maven (e.g. plugins, archetypes, the dependency mechanism, profiles, repositories, scopes...) stepwise.

First of all Maven 2 needs to be installed, which can be downloaded at http://maven.apache.org/download.html. A good help on installing Maven can be found here. Having a Debian-based Linux (e.g. Ubuntu) you are able to install everything automatically by executing:

sudo apt-get install maven2

After you've installed Maven 2 on your system you can run a litte test by executing "mvn --version" on your console. The result should be an information about the installed Maven version.

To start a simple new Maven 2 project please run "mvn archetype:generate". This will help you generating a specific Maven 2 project by using a Maven 2 archetype. Archetype are patterns for Maven 2 projects. We'll take a closer view on archetype in the third part of this tutorial-series.

After running "mvn archetype:generate" you'll see a bunch of Maven 2 archetypes:

  1. phil@scarface:/home/phil/experiments$ mvn archetype:generate
  2. [INFO] Scanning for projects...
  3. [INFO] Searching repository for plugin with prefix: 'archetype'.
  4. [INFO] ------------------------------------------------------------------------
  5. [INFO] Building Maven Default Project
  6. [INFO]    task-segment: [archetype:generate] (aggregator-style)
  7. [INFO] ------------------------------------------------------------------------
  8. [INFO] Preparing archetype:generate
  9. [INFO] No goals needed for project - skipping
  10. [INFO] Setting property: classpath.resource.loader.class => 'org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader'.
  11. [INFO] Setting property: velocimacro.messages.on => 'false'.
  12. [INFO] Setting property: resource.loader => 'classpath'.
  13. [INFO] Setting property: resource.manager.logwhenfound => 'false'.
  14. [INFO] [archetype:generate]
  15. [INFO] Generating project in Interactive mode
  16. [INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
  17. Choose archetype:
  18. 1: internal -> appfuse-basic-jsf (AppFuse archetype for creating a web application with Hibernate, Spring and JSF)
  19. 2: internal -> appfuse-basic-spring (AppFuse archetype for creating a web application with Hibernate, Spring and Spring MVC)
  20. 3: internal -> appfuse-basic-struts (AppFuse archetype for creating a web application with Hibernate, Spring and Struts 2)
  21. 4: internal -> appfuse-basic-tapestry (AppFuse archetype for creating a web application with Hibernate, Spring and Tapestry 4)
  22. 5: internal -> appfuse-core (AppFuse archetype for creating a jar application with Hibernate and Spring and XFire)
  23. 6: internal -> appfuse-modular-jsf (AppFuse archetype for creating a modular application with Hibernate, Spring and JSF)
  24. 7: internal -> appfuse-modular-spring (AppFuse archetype for creating a modular application with Hibernate, Spring and Spring MVC)
  25. 8: internal -> appfuse-modular-struts (AppFuse archetype for creating a modular application with Hibernate, Spring and Struts 2)
  26. 9: internal -> appfuse-modular-tapestry (AppFuse archetype for creating a modular application with Hibernate, Spring and Tapestry 4)
  27. 10: internal -> maven-archetype-j2ee-simple (A simple J2EE Java application)
  28. 11: internal -> maven-archetype-marmalade-mojo (A Maven plugin development project using marmalade)
  29. 12: internal -> maven-archetype-mojo (A Maven Java plugin development project)
  30. 13: internal -> maven-archetype-portlet (A simple portlet application)
  31. 14: internal -> maven-archetype-profiles ()
  32. 15: internal -> maven-archetype-quickstart ()
  33. 16: internal -> maven-archetype-site-simple (A simple site generation project)
  34. 17: internal -> maven-archetype-site (A more complex site project)
  35. 18: internal -> maven-archetype-webapp (A simple Java web application)
  36. 19: internal -> jini-service-archetype (Archetype for Jini service project creation)
  37. 20: internal -> softeu-archetype-seam (JSF+Facelets+Seam Archetype)
  38. 21: internal -> softeu-archetype-seam-simple (JSF+Facelets+Seam (no persistence) Archetype)
  39. 22: internal -> softeu-archetype-jsf (JSF+Facelets Archetype)
  40. 23: internal -> jpa-maven-archetype (JPA application)
  41. 24: internal -> spring-osgi-bundle-archetype (Spring-OSGi archetype)
  42. 25: internal -> confluence-plugin-archetype (Atlassian Confluence plugin archetype)
  43. 26: internal -> jira-plugin-archetype (Atlassian JIRA plugin archetype)
  44. 27: internal -> maven-archetype-har (Hibernate Archive)
  45. 28: internal -> maven-archetype-sar (JBoss Service Archive)
  46. 29: internal -> wicket-archetype-quickstart (A simple Apache Wicket project)
  47. 30: internal -> scala-archetype-simple (A simple scala project)
  48. 31: internal -> lift-archetype-blank (A blank/empty liftweb project)
  49. 32: internal -> lift-archetype-basic (The basic (liftweb) project)
  50. 33: internal -> cocoon-22-archetype-block-plain ([http://cocoon.apache.org/2.2/maven-plugins/])
  51. 34: internal -> cocoon-22-archetype-block ([http://cocoon.apache.org/2.2/maven-plugins/])
  52. 35: internal -> cocoon-22-archetype-webapp ([http://cocoon.apache.org/2.2/maven-plugins/])
  53. 36: internal -> myfaces-archetype-helloworld (A simple archetype using MyFaces)
  54. 37: internal -> myfaces-archetype-helloworld-facelets (A simple archetype using MyFaces and facelets)
  55. 38: internal -> myfaces-archetype-trinidad (A simple archetype using Myfaces and Trinidad)
  56. 39: internal -> myfaces-archetype-jsfcomponents (A simple archetype for create custom JSF components using MyFaces)
  57. 40: internal -> gmaven-archetype-basic (Groovy basic archetype)
  58. 41: internal -> gmaven-archetype-mojo (Groovy mojo archetype)
  59. Choose a number:  (1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/21/22/23/24/25/26/27/28/29/30/31/32/33/34/35/36/37/38/39/40/41) 15: :

Now it's up to you to choose. In this example we'll use the archetype 15 "maven-archetype-quickstart". Type "15" and press [Return]. After you choosed your archetype you'll be asked for project-specific settings:

  1. Define value for groupId: : com.unitedcoders
  2. Define value for artifactId: : MyExampleApp
  3. Define value for version:  1.0-SNAPSHOT: : 0.0.1-SNAPSHOT
  4. Define value for package:  com.unitedcoders: : com.unitedcoders.examples

The artifactId defines how the project and accordingly our java artifact will be called. The groupId defines to which group the artifact should belong. At the version prompt you should place the initial version number for your project (In this case: 0.0.1-SNAPSHOT). At least we'll define the main package for our java code. If you have entered everything right, you'll be asked to confirm your informations.

  1. Confirm properties configuration:
  2. groupId: com.united-coders
  3. artifactId: MyExampleApp
  4. version: 0.0.1-SNAPSHOT
  5. package: com.united-coders.examples
  6.  Y: : y

If everything looks like you expected ist please go on by entering "y" for YES.

  1. [INFO] ----------------------------------------------------------------------------
  2. [INFO] Using following parameters for creating OldArchetype: maven-archetype-quickstart:RELEASE
  3. [INFO] ----------------------------------------------------------------------------
  4. [INFO] Parameter: groupId, Value: com.united-coders
  5. [INFO] Parameter: packageName, Value: com.united-coders.examples
  6. [INFO] Parameter: package, Value: com.united-coders.examples
  7. [INFO] Parameter: artifactId, Value: MyExampleApp
  8. [INFO] Parameter: basedir, Value: /home/phil/experiments
  9. [INFO] Parameter: version, Value: 0.0.1-SNAPSHOT
  10. [INFO] ********************* End of debug info from resources from generated POM ***********************
  11. [INFO] OldArchetype created in dir: /home/phil/experiments/MyExampleApp
  12. [INFO] ------------------------------------------------------------------------
  13. [INFO] BUILD SUCCESSFUL
  14. [INFO] ------------------------------------------------------------------------
  15. [INFO] Total time: 3 minutes 28 seconds
  16. [INFO] Finished at: Fri Apr 17 12:05:44 CEST 2009
  17. [INFO] Final Memory: 9M/124M
  18. [INFO] ------------------------------------------------------------------------
  19. phil@scarface:/home/phil/experiments$

Congratulations! You've created a simple Maven 2 project structure. Let's take a look what happened. Navigate to your projects rootfolder and take a look on the contents:

Maven 2 project structure

You'll see that your project contains 3 files: pom.xml, App.java and AppTest.java. The pom.xml contains your projects Maven 2 configuration. Please take a look on the Maven website for further informations on how the pom configures your project and how to manage your applications dependencies and dpendency versions. The class App.java is a really simple example class and - as you certainly expected - the class AppTest.java contains associated JUnit testcase. Now you are able to run some Maven targets on your project. Run the following targets on your project and take a look on what will happen:

  • mvn test (runs the projects testcases)
  • mvn clean (removes the projects "target"-folder)
  • mvn package (build the artifact)
  • mvn eclipse:eclipse (create a .project-File to make the project eclipse-importable)

Let's take a closer look at the pom.xml's (POM - project object model) contents:

  1. <project xmlns="http://maven.apache.org/POM/4.0.0" [...] >
  2.   <modelVersion>4.0.0</modelVersion>
  3.   <groupId>com.unitedcoders</groupId>
  4.   <artifactId>MyExampleApp</artifactId>
  5.   <packaging>jar</packaging>
  6.   <version>0.0.1-SNAPSHOT</version>
  7.   <name>MyExampleApp</name>
  8.   <url>http://maven.apache.org</url>
  9.   <dependencies>
  10.     <dependency>
  11.       <groupId>junit</groupId>
  12.       <artifactId>junit</artifactId>
  13.       <version>3.8.1</version>
  14.       <scope>test</scope>
  15.     </dependency>
  16.   </dependencies>
  17. </project>

The groupId, the artifactId and the version we've entered during the project generation process can now be found in the pom.xml. The artifactId is also used as the projects name. The xml-node "modelVersion" declares to which version of project descriptor this pom.xml conforms. "packaging" defines the type of artifact this project produces (jar, war,...). In this case the default "jar" is used. So our project will create a jar-file on the "package" target. At the xml-node "url" the projects url is defined. The default url is "http://maven.apache.org". You can edit this entry and insert the URL of this project at a continous integration tool or the projects SVN url. Underneath these project configurations you can see the xml-node "dependencies". This node contains all of the projects dependencies (in this case only junit 3.8.1). In the next part of this tutorial series we will focus on those dependencies and scopes.

Further Maven 2 articles:
Maven 2 (Part 2): Dependencies, properties and scopes
Maven 2 (Part 3): Configuring eclipse for Apache Maven 2 projects

parfum

de goedkoopste parfum winkels op een rij

Vakantie in egypte

Vakantie aanbiedingen

Comments

Anonymous's picture

just for bigger java projects that use a huge set of dependencies could this result in conflict situations.
When certain dependencies use other dependencies with different versions.

Nico Heid's picture

this is true, but with version ranges you have a chance to spot these problems early and find a solution. A bad case is if some dependency you use overwrites one of your dependencies because you haven't specified the range.

e.g you specified

  1. <artifactId>supertool</artifactId>
  2. <version>2.4</version>

but some other jar transitively uses

  1. <artifactId>supertool</artifactId>
  2. <version>[,2.0]</version>

So that your version gets replaced. You'll run into some trouble with that.

Whereas if you had specified a minimum version you'll get a failure notice -> fail early

see: http://www.sonatype.com/books/maven-book/reference/pom-relationships-sec...

Alberto Perri's picture

Hi Nico,

i have done the following:

mvn archetype:generate -DgroupId=org.sonatype.mavenbook.simple -DartifactId=simple -DpackageName=org.sonatype.mavenbook -Dversion=1.0-SNAPSHOT
mvn compile
mvn install

Which ran OK. But when i try to run the jar file doing this
java -cp target/simple-1.0-SNAPSHOT.jar org.sonatype.mavenbook.App

I get the following error:

Exception in thread "main" java.lang.NoClassDefFoundError: org/sonatype/mavenboo
k/App
Caused by: java.lang.ClassNotFoundException: org.sonatype.mavenbook.App
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
Could not find the main class: org.sonatype.mavenbook.App. Program will exit.

Have you any idea what i should do?

A similar procedure using:

mvn archetype:create -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=com.mycompany.app -DartifactId=my-app
mvn compile
mvn install
java -cp target/my-app-1.0-SNAPSHOT.jar com.mycompany.app.App

Works wonderfully,
Thanks in advance,
Alberto

Nico Heid's picture

hi,
the article is by Phillip ;-) so Phillip, any idea?

To me it seems like a classpath problem.
I think in the first case the App should be under: org.sonatype.mavenbook.simple.App given the groupId you're using.

Can you try it?

Anonymous's picture

It is nice to have some articles showing Maven 2 from the beginning.

Anonymous's picture

Thank you so much for this tutorial--it was extremely helpful to me!

Divya's picture

Wow! Your sample project not only helped me set up my first successful Maven project but also resolved 2 day long pending issues with my other project.
Thanks a lot.

good post's picture

It's a very good article for beginners...it's detailed and step-by-step...thank you.