Maven is a tool for managing Java projects such as compilation, testing, packaging, documentation, and distribution.
Maven consists of the following:
- A set of conventions addressing dependency management, directory layouts, and build workflows.
- An xml schema for project configuration, the Project Object Model (POM)
- A plugin architecture that delegates the execution of project tasks to external components.
Installing and configuring
You can download the Maven from http://maven.apache.org/download.cgi. Installation is simple
- Extract the contents to any folder
- Set the environment variable M2_HOME to point to <install_dir>\apache-maven-3.6.1
- Add ${M2_HOME}\bin to your execution path.
Standard Directory Layout
Maven defines a standard project directory layout (https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html)
${project.basedir} is a standard Maven property that identifies the root directory of the current project.
${project.basedir}
|———\src
|———\main
|———\java
|———\resources
|———\webapp
|———\test
|———\java
|———\resources
|———\target
POM Outline
<project>
<groupId/>
<artifactId/>
<version/>
<packaging/>
<properties/>
<dependencies/>
<build/>
<profiles/>
</project>
A pom file can be used in following ways:
- Default—To build an artifact
- Parent—To provide a single source of configuration information to be inherited by child projects
- Aggregator—To build a group of projects
GAV Coordinates
The POM defines five elements, referred to as coordinates, that identify Maven artifacts. The acronym GAV refers to the three coordinates that must always be specified: <groupid>, <artifactId>, and <version>.
- <groupId> : is a universally unique identifier for a project or a group of projects. The is often the fully qualified Java package name.
- <artifactId> : identifies an artifact that is distinct with respect to a <groupId>
- <type> : refers to the type of the artifact of the project (corresponding to the <packaging> value). Default value is jar. E.g, pom, jar, war, ear.
- <version> identifies a version of an artifact.
- <classifier> is used to distinguish artifacts that belong to the same POM but that will built differently. E.g, javadoc, sources, jdk17.
Full coordinate expression has the following format:
artifactId:groupId:packaging:version:classifier
Dependencies
Dependencies are the external artifacts required to compile and execute it. A complex project can have a deep tree of dependencies; Maven provides a variety of facilities for understanding and managing it.
<dependencies>
<dependency>
<groupId/>
<artifactId/>
<version/>
<type/>
<scope/>
<systemPath/>
</dependency>
</dependencies>
The GAV coordinates are always required in a <dependency> declaration. The <type> and <scope> are required for values other than the default jar and compile.
The <scope> element can have the following values:
- compile—needed for compilation and execution (default)
- runtime—needed for execution only
- optional—not seen as a transitive dependency by other projects that reference the artifact produced by this project
- provided—not to be included in the WEB-INF/lib of the WAR
- test—needed for compilation and execution of tests only
- import—it import the contents of the <dependencyManagement> of an external POM.
Dependency Management
The <dependencyManagement> element contains <dependency> declaration that can be used by the other projects. Child projects will inherit these declarations automatically. Other projects can import them by using the import scope.
Build Lifecycles
A maven build lifecycle is a well-defined process for building and distributing an artifact.
- validate—checks whether the project is correct and all necessary information is available
- process-sources—Processes the source code; e.g, to filter any values
- compile—Compile the source code of the project
- process-test-resources—Copies and processes the resources into the test destination directory
- test-compile—Compiles the test source code
- test—Tests the compile source code
- package—Packages the compiled code in its distributable format
- integration-test—Processes and deploys the package into an environment where integration tests can be run
- verify—Runs any checks to verify the package is valid and meets quality criteria
- install—Installs the package in the local repository, where it can be referenced as a dependency by other locally built projects.
- deploy—Uploads the final artifact to a remote repository for sharing with other developers and projects
Executing one of these phases will invoke all preceding phases.
Plugins
Although Maven coordinates execution of all the build lifecycle phases, it doesn’t implement them directly. It delegates them to plugins. The Apache Maven provides plugins for all of the tasks defined by the standard build lifecycle; many more are produced by third parties to handle custom tasks of all kinds.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
</plugin>
Above plugin can be used to be able to execute the projects from the command line.
Plugin Management
The <pluginManagement> declares information that can be used by other POMs. But this is only for child POMs.
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
</plugin>
</plugins>
</pluginManagement>
</build>
Can inherit Plugin from Child POM as below
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Profiles
A <profiles> is a customized set of POM elements that can be enabled automatically or manually to alter the behavior of the POM. E.g, you can define a profile that will set build parameters depending on the JDK version, OS, or target deployment environment.
Profile is refer explicitly with the command-line -P flag.
mvn -P jdk16 clean install
Repositories
A maven artifact repository may be remote or local.
- A remote repository is a service from which Maven downloads dependencies referenced in POM files. If you have upload permission, you may upload the artifacts produced by your projects.
- A local repository is a local directory that contains artifacts downloaded from remote repositories as well as artifacts you have built and installed on your local machine.
Snapshots and Releases
Remote repositories generally define separates areas for artifacts that are under development and those that are stable or production releases. These are referred as Snapshot and Release repositories.
Artifacts with a <version> ending in -SNAPSHOT will be treated as one that has not yet been released. Such an artifact can be uploaded to the repository repeatedly with the same <version>.
When you build a project that has a SNAPSHOT dependency, Maven will check whether there is a copy in the local repository. If there is not, it will attempt to retrieve it from the remote repository with the latest timestamp. If the artifact does exist locally and the current build is the first of the day, by default Maven will attempt to update the local copy. This behavior can be configured using settings in Maven’s configuration file(settings.xml) or with the command-line.