# Maven

## Definition

Quoted from maven.apache.org :

> Maven is an attempt to apply patterns to a project's build infrastructure in order to promote comprehension and productivity by providing a clear path in the use of best practices In a nutshell, maven helps you by managing different side of your project like :
>
> * Dependencies, SCMs(Supply-chain-management software)
> * Documentation, Reporting
> * Builds, Releases, Distribution

To make this possible, Maven use an archetype mechanism.

## [Archetypes](https://maven.apache.org/guides/introduction/introduction-to-archetypes.html)

Quoted from maven.apache.org :

> In short, Archetype is a Maven project templating toolkit. An archetype is defined as an original pattern or model from which all other things of the same kind are made. The name fits as we are trying to provide a system that provides a consistent means of generating Maven projects.

Basically, you can use archetypes to start your project from a template one. For example, if you wish to start a J2EE project, you might want to use the `maven-archetype-j2ee-simple` archetypes, since this archetype helps to generate a simplifed sample J2EE application.

The strength of this system is that you can create your own archetype. This way you can helps people get up and running any kind of configuration. It might not be accurate but you can picture this as a already setup docker container.

### Structure

An archetype is made up of:

* An archetype descriptor (`archetype-metadata.xml` in directory: `src/main/resources/META-INF/maven/`) : It lists all the files that will be contained in the archetype and categorizes them so they can be processed correctly by the archetype generation mechanism.
* The prototype files that are copied by the archetype plugin (directory: `src/main/resources/archetype-resources/`)
* The prototype pom (pom.xml in: `src/main/resources/archetype-resources`)
* A pom for the archetype (`pom.xml` in the archetype's root directory). We will see what is it in the related section.

## [The Project Object Model (POM)](https://maven.apache.org/guides/introduction/introduction-to-the-pom.html)

Quoted from maven.apache.org :

> The POM is the basic unit of work in Maven. This is important to remember because Maven is inherently project-centric in that everything revolves around the notion of a project. In short, the POM contains every important piece of information about your project and is essentially one-stop-shopping for finding anything related to your project

Basic `pom.xml` file contains the following :

* *project* : This is the top-level element in all Maven pom.xml files.
* *modelVersion* : This element indicates what version of the object model this POM is using. Changes very infrequently but is mandatory.
* *groupId* : This element indicates the unique identifier of the organization or group that created the project. For example org.apache.maven.plugins is the designated groupId for all Maven plugins.
* *artifactId* : This element indicates the unique base name of the primary artifact being generated by this project. The primary artifact for a project is typically a JAR file. Secondary artifacts like source bundles also use the artifactId as part of their final name. A typical artifact produced by Maven would have the form -. (for example, myapp-1.0.jar).
* *packaging* : This element indicates the package type to be used by this artifact (e.g. JAR, WAR, EAR, etc.). This not only means if the artifact produced is JAR, WAR, or EAR but can also indicate a specific lifecycle to use as part of the build process. (The lifecycle is a topic we will deal with further on in the guide. For now, just keep in mind that the indicated packaging of a project can play a part in customizing the build lifecycle.) The default value for the packaging element is JAR so you do not have to specify this for most projects.
* *version* : This element indicates the version of the artifact generated by the project. Maven goes a long way to help you with version management and you will often see the SNAPSHOT designator in a version, which indicates that a project is in a state of development. We will discuss the use of snapshots and how they work further on in this guide.
* *name* : This element indicates the display name used for the project. This is often used in Maven's generated documentation.
* *url* : This element indicates where the project's site can be found. This is often used in Maven's generated documentation.
* *description* : This element provides a basic description of your project. This is often used in Maven's generated documentation.

You can find more elements here : [POM Reference](https://maven.apache.org/ref/3.6.1/maven-model/maven.html)

### [Dependencies](https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html)

Quoted from maven.apache.org :

> The dependencies section of the pom.xml lists all of the external dependencies that our project needs in order to build (whether it needs that dependency at compile time, test time, run time, or whatever)

For each external dependency, you'll need to define at least 4 things: `groupId`, `artifactId`, `version`, and `scope`. The groupId, artifactId, and version are the same as those given in the pom.xml for the project that built that dependency. The scope element indicates how your project uses that dependency, and can be values like compile, test, and runtime

## Standard Directory Layout

Maven ask to follow common directory layout. If you can follow those, it should be overridden via the project descriptor.

* Main locations:

| `src/main/java`             | `src/main/resources`          | `src/test/java` | `src/it`                                  | `src/assembly`       |
| --------------------------- | ----------------------------- | --------------- | ----------------------------------------- | -------------------- |
| Application/Library sources | Application/Library resources | Test sources    | Integration Tests (primarily for plugins) | Assembly descriptors |

* Others locations:

| `src/main/filters`    | `src/main/webapp`       | `src/test/resources` | `src/test/filters`         | `src/site` |
| --------------------- | ----------------------- | -------------------- | -------------------------- | ---------- |
| Resource filter files | Web application sources | Test resources       | Test resource filter files | Site       |

To summary, their should be only the `src` and `target` folders at the root (along with metadata like `.git` and `.idea`) The `target` directory is used to house all output of the build. The `src` directory contains all of the source material for building the project, its site and so on.

## [Maven Repositories](https://maven.apache.org/guides/introduction/introduction-to-repositories.html)

There are two types of repositories in Maven :

* Local : a directory on the computer where Maven runs. It caches remote downloads and contains temporary build artifacts that you have not yet released.
* Remote : Remote repositories refer to any other type of repository, accessed by a variety of protocols such as `file://` and `http://`.

*Note* : Local and remote repositories are structured the same way.

### Using it

You should not do anything for local repository. Whereas you can either download or uploade for remote repositories.

* Download : This action is triggered when you add a dependencies in your `pom.xml` for example. By default, Maven will download from the central repository. If you want to override it, you will have to use [mirrors](https://maven.apache.org/guides/mini/guide-mirror-settings.html) (something like JFrog, Sonatype, etc.). Settings up a mirror can be good to save bandwith and time, if the mirror is geographically closer, since it will retrieve artifacts from it. It can also be used as a proxy when writing your own [repository manager](https://maven.apache.org/repository-management.html). *Note* : Note that there can be at most one mirror for a given repository. If you want to provide a combined view of several repositories, use a repository manager instead.
* Upload : You can either upload to the [Repository Center](https://maven.apache.org/repository/index.html) or even your own internal repository. (More on that ?)

## Acknowledgements

* [Maven - apache.org](https://maven.apache.org/guides/getting-started/index.html)
