Monday, August 28, 2017

Creating a Simple Maven Project

Generating a simple project with Maven and Eclipse

To generate a project with maven from command line:

 mvn -B archetype:generate \
-DarchetypeGroupId=org.apache.maven.archetypes \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DgroupId=com.mycompany.application \
-DartifactId=maven-project \
-Dpackage=com.mycompany.application \
-Dversion=1.0
  • the maven command mvn archetype:generate executes the generate goal of the archetype plugin
  • an archetype is defined as a "model from which similar thing are patterned; a prototype"
  • when you run the archetype:generate goal you pass the goal parameter: archetypeArtifactId=maven-archetype-quickstart
  • you can select the maven archetypes that fits your purpose
  • the maven-archetype-quickstart is the most basic archetype to create a java project

To generate a project with maven from eclipse:

  • select new -> Project -> Maven -> Maven Project
  • in the filter text field, write: org.apache.maven
  • select the artifact with artifactId: maven-archetype-quickstart
  • assign the values for the following text field:
    • Group Id = com.mycompany.application
    • Artifact Id = my-project
    • Version = 1.0
    • Package = com.mycompany.application

Have a look at the directory structure of the project created by maven:

                                                      my-project/
                                                         |__pom.xml
                                                         |__src/main/java
                                                         |__src/test/java
  • the archetype plugin created a my-project directory that matches the ArtifactId parameter
  • the project has a project object model in a file named pom.xml
  • the project source code is placed under src/main/java as classpath resources should be under src/main/resources
  • test cases are placed under src/test/java as classpath resources should be under src/test/resources
Building a simple project

The maven command to build the project is mvn install

  • this command executes a maven lifecycle phase that compiles and installs a maven artifact in your local repository.
Project Object Model in pom.xml file
<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
                                              _________________________________
  <groupId>com.mycompany.application</groupId>
  <artifactId>maven-project</artifactId>          coordinates elements = {groupId,artifactId,version,packaging}
  <version>1.0</version>           
  <packaging>jar</packaging>
                                         ______________________________________ 
  <name>maven-project</name>                     description elements = {name,url}
  <url>http://maven.apache.org</url>     ______________________________________

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>             dependencies elements
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>            _________________________________________________
</project>
  • the four elements: groupId, artifactId, packaging and version are known as the maven coordinates
  • name and url are human readable descriptive elements
  • the dependencies element defines a single dependency on JUnit framework
Maven Core Concepts: plugin, goal, lifecycle, phase, coordinates
maven plugins and goals

The maven command mvn archetype:generate executes a maven plugin goal

  • where archetype is the plugin name and generate is the goal name.
  • when maven executes a plugin goal, it prints plugin name and goal name: [INFO] [archetype:generate]

What is a Maven plugin ?

  • a maven plugin is a collection of one or more goals
    • for example, the Compiler core plugin contains goals for compiling source code and unit tests
    • for example, the Surefire core plugin contains goals for executing unit tests and generating reports
    • for example, the Jar core plugin provides the capability to build jars
    • an example of specialized plugins is the Hibernate3 plugin
                               _________________________________________
                              |   ______    ______    ______    ______   |
                              |  |      |  |      |  |      |  |      |  |
                              |  | GOAL |  | GOAL |  | GOAL |  | GOAL |  |
                              |  |______|  |______|  |______|  |______|  |
                              |                                          |
                              |                  PLUGIN                  |
                              |__________________________________________|                           

What is a Maven goal ?

  • a maven goal is a task that may be executed alone or with other goals within a build
    • for example, the compile goal of the Compiler plugin and the test goal of the Surefire plugin
  • the notation to refer to plugin goal is PluginId:goalId
  • you can customize goal behavior, passing parameters, for example when you run the Archetype:generate goal you pass the artifactId parameter

What maven plugins are for ?

  • the core of maven does not handle the project build: it does not know how to compile code
  • maven delegates his work to maven plugins, which are downloaded as needed and updated from maven repository
maven lifecycle

The maven commands for the simple project: mvn install executes a maven lifecycle

What are Maven lifecycle ?

  • Maven is based on the concept of a build lifecycle.
  • A lifecycle is a well defined process for building and distributing a project.

There are three built-in build lifecycles:

  • the default lifecycle handles the project build and distribution
  • the clean lifecycle handles project cleaning
  • the site lifecycle handles the creation of documentation of the project
maven lifecycle phases

Each build lifecycles is defined as a list of build phases, where a build phase represents a step in the lifecycle.

For example, the main phases of the default lifecycle are:

    validate - validate the project is correct and all necessary information is available
    compile - compile the source code of the project
    test - test the compiled source code using a suitable unit testing framework.
    package - package the compiled code in distributable format, such as a .jar file.
    verify - run any checks on results of integration tests to ensure quality criteria are met
    install - install the package into the local repository, for use as a dependency in other projects locally
    deploy - copy the final package to the remote repository for sharing with other developers and projects.

The lifecycle phases are executed sequentially to complete the default lifecycle.

a maven goal binds to a phase
  • maven lifecycle phases are not clearly defined, they mean different things for different projects
  • plugin goals can be attached to a lifecycle phase: each phase may have zero or more goals linked to it.
  • as maven moves through the phases of a lifecycle it executes the plugin attached to each particular phase.
    • for example, when you run the mvn install command on the simple project, maven executes many goals and, when it reachs the package phase, it run the jar goal of the Jar plugin, because the simple project has a jar packaging type.
  • to sum up, when you execute the mvn install command, maven executes all the phases untill the install phase and as it steps through each phase it execute all the goals bound to the current phase.
the project object model - pom.xml

The Archetype plugin generated a pom.xml file: the Project Object Model

  • the POM file is a declarative description of the project
  • goals execute in the context of the POM: when maven executes a goal, it has access to the information defined in the POM
    • for example, when the Compiler:compile goal executes, it looks at the POM file to check whether there are any parameter for the compile goal.
  • Note: maven commands are executed in the context of the effective POM, which is the result of this pom.xml, a super-POM (defined within maven) and a user defined settings.

The project's POM defines its project:

  • the POM provides a set of unique project coordinates
  • the POM defines the the relationship between this project and others through project dependencies, parent project and project prerequisites
  • the POM customizes plugin behavior
maven coordinates

Maven coordinates are a set of identifiers used in maven POMs

  • maven coordinates uniquely identify a project, a dependency, a plugin.

Project's coordinates in the pom.xml file

<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.mycompany.application</groupId>              |
  <artifactId>my-project</artifactId>                       | MAVEN
  <packaging>jar</packaging>                                | COORDINATES
  <version>1.0</version>  __________________________________|
                                             
  <name>a nice application</name>
  <url>http://mycompany.com</url>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

</project>

The project's coordinates in the above POM are the four values: groupId, artifactId, version and packaging

  • groupId: the group, company, organization. The convention is the same of java package name, the reverse domain name of the organization that creates the project. For example: org.apache.struts
  • artifactId: a unique identifier that names a single project under a the groupId. For example: struts-core
  • version: the release number of a project
  • packaging: the type of project which describes the packaged output produced by a project.

Note: the three values: groupId, artifactId and version make up a project unique identifier; the packaging identifier is part of the maven coordinates, but is not part of the project unique identifier.

Maven coordinates are written using a separator colon in the format: groupId:artifactId:packaging:version

  • for example, maven coordinates for the previous project are: com.mycompany.application:my-project:jar:1.0

Maven coordinates allow to locate a particular project in the space of maven projects

  • maven repository are organized according to these identifiers
  • if a maven project wants to use another project, all it has to do is add it as a dependency using the maven coordinates
   __________________________________________
  |                                          |
  |  org.apache.struts (groupid)             |
  |                                          |
  |                                          |
  |  (artifactId:version:packaging)          |
  |  struts-core:1.3.8:jar                   |
  |  struts-taglib:1.3.8:jar                 |
  |  struts-tiles:1.3.8:jar                  |
  |__________________________________________|
maven repositories

Maven downloads files from a maven central repository

  • in fact, maven does not ship with plugins, but plugins and dependencies are retrieved as needed from maven central repository

Maven artifacts are downloaded from maven central repository and stored in user's local repository

  • maven repositories store artifacts in a directory structure that matches a project coordinates:
    /groupId/artifactId/version/artifact-version.packaging
  • if you run the mvn install command, you will see the JAR artifact created from the simple project in your local repository
maven’s dependency management

Maven ability to locate an artifact based on coordinate allow to define dependencies in project's POMs.

  • for example, the simple project defines a dependency on JUnit
  • complex project's POMs contain multiple dependencies and dependencies that depends on other artifacts.
    • maven supports transitive dependencies: if your project depends on a library (such as Spring) that depends on many other libraries, you don't have to all these dependencies in your project's POM explicitly; your project simply depends on the library of interest and maven add the dependencies of this library implicitly.

Maven has different scopes for dependencies

  • for example, the simple project defines a dependency on JUnit with a scope of test
  • when maven creates a JAR artifact, dependencies are used for compilation and not bundled with the JAR
  • when maven creates a WAR or EAR artifact you may want to:
    • bundle dependencies with the generated artifact using the default compile scope
    • exclude dependencies from the generated artifact using the provided scope
      • the provided scope indicates you expect a JDK or Java container to provide the dependency at runtime. For example, you use the provided scope for servlet API jar that ypu don't want to be included in the WEB-INF/lib directory.

No comments :

Post a Comment