Maven
Maven is a build automation tool used primarily for Java projects. Maven builds a project using its project object model (POM) and a set of plugins.
Maven’s primary goal is to allow a developer to comprehend the complete state of a development effort in the shortest period of time. In order to attain this goal, Maven deals with several areas of concern:
- Making the build process easy
- Providing a uniform build system
- Providing quality project information
- Encouraging better development practices
Maven provides useful project information that is in part taken from your POM and in part generated from your project’s sources. For example, Maven can provide:
- Change log created directly from source control
- Cross-referenced sources
- Mailing lists managed by the project
- Dependencies used by the project
- Unit test reports including coverage
Third-party code analysis products also provide Maven plugins that add their reports to the standard information given by Maven.
Maven Archetypes
A Maven archetype is an abstraction of a kind of a project that can be instantiated into a concrete customized Maven project. In short, it's a template project template from which other projects are created. The main benefit of using archetypes is to standardize project development and to enable developers to easily follow best practices while bootstrapping their projects faster.
Using Maven Archetype plugin
The maven-archetype plugin allows the user to create a Maven project through the generate goal and existing archetype.
To create a project from the archetype, we can use:
mvn archetype:generate -DgroupId={GroupId} -DarchetypeArtifactId={ArtifactID_of_Archetype}
-DarchetypeVersion={Version_of_Archetype}
-DgroupId={GroupID_of_Project}
-DartifactId={ArtifactID_of_Project}
-Dversion={Version_of_Project}
https://maven.apache.org/guides/getting-started/maven-in-five-minutes.html
Build Phases and Goals in Maven
The Maven build follows a specific life cycle to deploy and distribute the target project.
There are three built-in life cycles:
- default: the main life cycle as it's responsible for project deployment
- clean: to clean the project and remove all files generated by the previous build
- site: to create the project's site documentation
Each life cycle consists of a sequence of phases. The default build life cycle consists of 23 phases as it's the main build lifecycle. On the other hand, clean life cycle consists of 3 phases, while the site lifecycle is made up of 4 phases.
Maven Phase
A Maven phase represents a stage in the Maven build lifecycle. Each phase is responsible for a specific task.
Here are some of the most important phases in the default build lifecycle:
- validate: check if all information necessary for the build is available
- compile: compile the source code
- test-compile: compile the test source code
- test: run unit tests
- package: package compiled source code into the distributable format (jar, war, …)
- integration-test: process and deploy the package if needed to run integration tests
- install: install the package to a local repository
- deploy: copy the package to the remote repository
For the full list of each lifecycle's phases, check out the Maven Reference. Phases are executed in a specific order. This means that if we run a specific phase using the command:
mvn <phase>
This won't only execute the specified phase but all the preceding phases as well. For example, if we run the deploy phase – which is the last phase in the default build lifecycle – that will execute all phases before the deploy phase as well, which is the entire default lifecycle:
mvn deploy
Each phase is a sequence of goals, and each goal is responsible for a specific task. When we run a phase – all goals bound to this phase are executed in order.Maven Goal
Here are some of the phases and default goals bound to them:
- compiler:compile – the compile goal from the compiler plugin is bound to the compile phase
- compiler:testCompile is bound to the test-compile phase
- surefire:test is bound to test phase
- install:install is bound to install phase
- jar:jar and war:war is bound to package phase
Maven Plugins
Maven is - at its heart - a plugin execution framework; all work is done by plugins. A Maven plugin is a group of goals. However, these goals aren't necessarily all bound to the same phase.
There are the build and the reporting plugins:
- Build plugins will be executed during the build and they should be configured in the
<build/>
element from the POM. - Reporting plugins will be executed during the site generation and they should be configured in the
<reporting/>
element from the POM.
Configuration of Maven Plugins
Maven plugins needs to be configured before using them. We can add the configuration details in pom.xml file of the maven project.
For example, here's a simple configuration of the Maven Failsafe plugin which is responsible for running integration tests:
integration-test: run integration testsAs we can see, the Failsafe plugin has two main goals configured here:
- verify: verify all integration tests passed
Executing Goals provided by Maven Plugin
Goals provided by Maven Plugins can be executed using the following syntax:
mvn [plugin-name]:[goal:name]
mvn failsafe:integration-test
For example, to run integration-test goal from Failsafe plugin, we need to run:
Maven Core Plugins
A list of maven core plugins are given below:
Plugin | Description |
---|
clean | clean up after build. |
compiler | compiles java source code. |
deploy | deploys the artifact to the remote repository. |
failsafe | runs the JUnit integration tests in an isolated classloader. |
install | installs the built artifact into the local repository. |
site | generates a site for the current project. |
surefire | runs the JUnit unit tests in an isolated classloader. |
verifier | verifies the existence of certain conditions. It is useful for integration tests. |
Other Important Maven Plugins
Plugin | Description |
---|
JaCoCo | code coverage reports generator for Java projects. |
formatter-maven-plugin | allows formatting java source code using the Eclipse code formatter. |
|
|
Pom.xml
POM is an acronym for Project Object Model. It is an XML file that contains information about the project and configuration details used by Maven to build the project. The pom.xml file contains information such as dependencies, build directory, source directory, test source directory, plugin, goals etc. Maven reads the pom.xml file, then executes the goal.
Element | Description | Example | Possible Parents |
<project> | This is the root tag in pom.xml file. All project related configuration are stored inside this tag. | <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 https://maven.apache.org/xsd/maven-4.0.0.xsd"/> | N/A |
<modelVersion> | This element indicates what version of the object model this POM is using. The version of the model itself changes very infrequently but it is mandatory in order to ensure stability of use if and when the Maven developers deem it necessary to change the model. | <modelVersion>4.0.0</modelVersion> | <project> |
<groupId> | Base name of the company or group that created the project. | <groupId>com.connectwise</groupId> | 1. <project> |
2. <dependency> |
3. <plugin> |
|
<artifactId> | Name of the project | <artifactId>workitems</artifactId> | 1. <project> |
2. <dependency> |
3. <plugin> |
|
<version> | Version of the project | <version>4.3.5.RELEASE</version> | 1. <project> |
| 2. <dependency> |
The first three of these (groupId:artifactId:version) combine to form the unique identifier for a maven project and are the mechanism by which you specify which versions of external libraries (e.g. JARs) your project will use. | 3. <plugin> |
| |
<packaging> | It specifies the type of artifact the project produces. When no packaging is declared, Maven assumes the packaging is the default: jar. | <packaging>war</packaging> | <project> |
<properties> | Maven properties are value placeholders. Their values are accessible anywhere within a POM by using the notation ${X}, where X is the property. Or they can be used by plugins as default values. | <properties> | <project> |
| |
They come in five different styles: | <maven.compiler.source>1.7</maven.compiler.source> |
| |
1. env.X: Prefixing a variable with "env." will return the shell's environment variable. The names of environment variables are normalized to all upper-case . | <maven.compiler.target>1.7</maven.compiler.target> |
2. project.x: A dot (.) notated path in the POM will contain the corresponding element's value. For example: <project><version>1.0</version></project> is accessible via ${project.version}. | |
3. settings.x: A dot (.) notated path in the settings.xml will contain the corresponding element's value. For example: <settings><offline>false</offline></settings> is accessible via ${settings.offline}. | <!-- Following project.-properties are reserved for Maven in will become elements in a future POM definition. --> |
4. Java System Properties: All properties accessible via java.lang.System.getProperties() are available as POM properties, such as ${java.home}. | |
| <!-- Don't start your own properties properties with project. --> |
| |
| <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
| |
| <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> |
| |
| </properties> |
<parent> | Maven supports the concepts of project inheritance. The packaging type required to be pom for parent and aggregation (multi-module) projects. we can add values to the parent POM, which will be inherited by its children. | <parent> | <project> |
|
<groupId>org.codehaus.mojo</groupId> |
|
<artifactId>my-parent</artifactId> |
|
<version>2.0</version> |
|
</parent> |
modules | A project with modules is known as a multi-module, or aggregator project. Modules are projects that this POM lists, and are executed as a group. | <modules> | <project> |
|
<module>my-project</module> |
|
<module>another-project</module> |
|
</modules> |
dependencyManagement | It is used by a POM to help manage dependency information across all of its children. If the my-parent project uses dependencyManagement to define a dependency on junit:junit:4.12, then POMs inheriting from this one can set their dependency giving the groupId=junit and artifactId=junit only and Maven will fill in the version set by the parent. | <dependencyManagement> | <project> |
|
<dependencies> |
|
<dependency> |
|
<groupId>junit</groupId> |
|
<artifactId>junit</artifactId> |
|
<version>4.12</version> |
|
</dependency> |
|
... |
|
</dependencies> |
|
</dependencyManagement> |
<dependencies> | It can be used to list down all the dependencies needed for the project. | <dependencies> | <project> |
|
<dependency> |
|
<groupId>junit</groupId> |
|
<artifactId>junit</artifactId> |
|
<version>4.12</version> |
|
</dependency> |
|
... |
|
</dependencies> |
<dependency> | This tag is used to specify the dependency details like groupId, artfactId, version. | <dependency> | <dependencies> |
|
<groupId>junit</groupId> |
|
<artifactId>junit</artifactId> |
|
<version>4.12</version> |
|
</dependency> |
<scope> | This tag defines the scope of a specific dependency. | <dependency> | <dependency> |
| |
There are 6 scopes: | <groupId>junit</groupId> |
| |
compile : Compile dependencies are available in all classpaths of a project. Furthermore, those dependencies are propagated to dependent projects. | <artifactId>junit</artifactId> |
provided : This scope is used to mark dependencies that should be provided at runtime by JDK or a container, hence the name. | |
runtime : The dependencies with this scope are required at runtime, but they're not needed for compilation of the project code. | <version>4.12</version> |
test : This scope is used to indicate that dependency isn't required at standard runtime of the application, but is used only for test purposes. | |
system : system scope is much similar to the provided scope. The main difference between those two scopes is that system requires us to directly point to a specific jar on the system. | <scope>test</scope> |
import : indicates that this dependency should be replaced with all effective dependencies declared in it's POM | |
| </dependency> |
<exclusions> | Exclusions tell Maven not to include the specified project that is a dependency of this dependency (in other words, its transitive dependency). | <exclusions> | <dependency> |
|
<exclusion> |
|
<groupId>org.apache.maven</groupId> |
|
<artifactId>maven-core</artifactId> |
|
</exclusion> |
|
</exclusions> |
<repositories> | Repositories are collections of artifacts which adhere to the Maven repository directory layout. This tag is used to configure alternate repositories where maven should try to look for the needed artifacts. | <repositories> | <project> |
|
<repository>...</repository> |
|
... |
|
</repositories> |
<repository> | This tag is used to configure a specific repository out of multiple options where maven should try to look for the needed artifacts. | <repository> | <repositories> |
|
<name>Nexus Snapshots</name> |
|
<id>snapshots-repo</id> |
|
<url>https://oss.sonatype.org/content/repositories/snapshots</url> |
|
<layout>default</layout> |
|
<releases> |
|
<enabled>false</enabled> |
|
</releases> |
|
<snapshots> |
|
<enabled>true</enabled> |
|
</snapshots> |
|
</repository> |
<pluginRepository> | This element each specify a remote location of where Maven can find new plugins. All plugin repositories can be clubbed under <pluginRepositories> tag. | <pluginRepositories> | <project> -><pluginRepositories> |
|
<pluginRepository> |
|
<id>apache.snapshots</id> |
|
<url>https://repository.apache.org/snapshots/</url> |
|
<releases> |
|
<updatePolicy>daily</updatePolicy> |
|
</releases> |
|
<snapshots> |
|
<updatePolicy>daily</updatePolicy> |
|
</snapshots> |
|
</pluginRepository> |
|
</pluginRepositories> |
<plugin> | This tag is used to configure a specific plugin. It includes details like groupId, artifactId and other configurations. All plugins are listed under <plugins> tag. | <plugin> | <plugins> |
|
<groupId>my.group</groupId> |
|
<artifactId>my-plugin</artifactId> |
|
<configuration> |
|
... |
|
</configuration> |
|
</plugin> |
<configuration> | This tag holds all the plugin specific configuration tags. | <plugin> | 1. <plugin> |
| 2. <execution> |
<groupId>org.apache.maven.plugins</groupId> | |
| |
<artifactId>maven-jar-plugin</artifactId> | |
| |
<version>2.6</version> | |
| |
<executions> | |
| |
<execution> | |
| |
<id>pre-process-classes</id> | |
| |
<configuration> | |
| |
<classifier>pre-process</classifier> | |
| |
</configuration> | |
| |
</execution> | |
| |
</executions> | |
| |
</plugin> | |
<executions> | This tag holds all execution related properties for a specific plugin. It contains sub-element <execution> which can contain a set of specific execution properties. | <plugin> | <plugin> |
|
<groupId>org.apache.maven.plugins</groupId> |
|
<artifactId>maven-jar-plugin</artifactId> |
|
<version>2.6</version> |
|
<executions> |
|
<execution> |
|
<id>pre-process-classes</id> |
|
<configuration> |
|
<classifier>pre-process</classifier> |
|
</configuration> |
|
</execution> |
|
</executions> |
|
</plugin> |
<goal> | This tag is used to specify which goal it should execute while building the project. All goal tags should be included in <goals> tag. | <plugin> | <execution>→ <goals> |
|
<artifactId>maven-antrun-plugin</artifactId> |
|
<version>1.1</version> |
|
<executions> |
|
<execution> |
|
<id>echodir</id> |
|
<goals> |
|
<goal>run</goal> |
|
</goals> |
|
</execution> |
|
</executions> |
|
</plugin> |
<phase> | This tag is used to specify in which phase it should execute the goals while building the project. | plugin> | <execution> → <phase> |
|
<artifactId>maven-antrun-plugin</artifactId> |
|
<version>1.1</version> |
|
<executions> |
|
<execution> |
|
<id>echodir</id> |
|
<goals> |
|
<goal>run</goal> |
|
</goals> |
|
<phase>verify</phase> |
|
</execution> |
|
</executions> |
|
</plugin> |
Comments
Post a Comment