The other essential concepts of Maven are discussed in the following sections.
Maven repositories are accessible locations designed to store the artifacts that Maven builds produce. To be more precise, a repository is a location to store a project's artifacts that is designed to match the Maven coordinates.
A Maven repository can be one of the following types:
A local repository is one that resides in the same machine where a Maven build runs. It is a .m2
folder located in the $USER_HOME
directory of the user's machine. It is created when the mvn
command is run for the very first time. However, to override the default location, open the settings.xml
file if it exists; else, create one in the $M2_HOMEconf
(for windows: %M2_HOME%conf
) folder and respective location as in the following code:
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> <localRepository>/opt/m2repos</localRepository> </settings>
When we run the Maven command, Maven will download dependencies to a custom path.
The central repository is the repository provided by the Maven community. It contains a large repository of commonly used libraries. This repository comes into play when Maven does not find libraries in the local repository. The central repository can be found at: http://search.maven.org/#browse.
Enterprises usually maintain their own repositories for the libraries that are being used for the project. These differ from the local repository; a repository is maintained on a separate server, different from the developer's machine and is accessible within the organization. Also, sometimes, there are cases where the availability of the libraries in central repositories is not certain, thus giving rise to the need for a remote repository.
For example, the following POM file mentions the remote repositories, where the dependency is not available in the central repository:
<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.packt.mvneclipse</groupId> <artifactId>hello-project</artifactId> <version>1.0</version> <dependencies> <dependency> <groupId>com.packt.commons</groupId> <artifactId>utility-lib</artifactId> <version>1.0.0</version> </dependency> <dependencies> <repositories> <repository> <id>packt.ser1</id> <url>http://download.packt.net/maven2/1</url> </repository> <repository> <id>packt.ser2</id> <url>http://download.packt.net/maven2/2</url> </repository> </repositories> </project>
The following figure illustrates the sequence in which the search operation is carried out in the repositories on execution of the Maven build:
Maven follows the ensuing sequence to search dependent libraries in repositories, and the sequence is explained as follows:
The powerful feature of Maven is its dependency management for any project. Dependencies may be external libraries or internal (in-house) libraries/project. Dependencies in POM can be stated under the following tags with the following attributes as shown:
<dependencies> <dependency> <groupId>org.testng </groupId> <artifactId>testng</artifactId> <version>6.1.1</version> <type>jar</type> <scope>test</scope> <optional>true</optional> </dependency> ... </dependencies>
The attributes used in the preceding code snippet are as follows:
groupId
, artifactId
, and version
: These are the Maven coordinates for dependency.type
: This is a dependency packaging type. The default type is JAR. We have already discussed this in an earlier section.scope
: This provides a mechanism of control over the inclusion of dependencies in the class path and with an application. We will talk about this scope in the next section.optional
: This indicates the dependency as optional when the project is a dependency. To put this in simple terms, consider that project A has the optional
dependency, which means it needs this library at build time. Now, project B has this project A that is dependency defined, so this implies B may not need A's dependency for its build and is a part of transitive dependencies.Dependency scopes control the availability of dependencies in a classpath and are packaged along with an application. There are six dependency scopes, which are described in detail as follows:
Compile
: This is the default scope if not specified. Dependencies with this scope are available in all classpaths and are packaged.Provided
: Similar to the compile
scope, however, this indicates JDK or the container to provide them. It is available only in compilation and test classpaths and is not transitive.Runtime
: This scope indicates that the dependency is not required for compilation but is available for execution. For example, a JDBC driver is required only at runtime, however the JDBC API is required during compile time.Test
: This scope indicates that the dependency is not required for normal use of the application, and it is only available for the test compilation and execution phases.System
: This is similar to the provided
scope but the explicit path to JARs on the local filesystem is mentioned. The path must be absolute such as $JAVA_HOME/lib
. Maven will not check the repositories; instead it will check the existence of the file.Project A depends on project B and project B depends on C—now C is a transitive dependency for A. Maven's strength lies in the fact that it can handle transitive dependencies and hide the chain of dependencies under the hood from a developer's knowledge. As a developer, the direct dependency of the project is defined, and all other dependencies' chain nuisance is dealt by Maven with effective version conflict management. Scope limits the transitivity of a dependency as discussed in the preceding section by allowing the inclusion of dependencies appropriate for the current stage of the build.
For more information, please visit http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html.
Transitive dependency is illustrated in the following figure:
Maven, essentially, is a plugin framework where every action is the result of some plugin. Each plugin consists of goals (also called Mojos) that define the action to be taken. To put it in simple words, a goal is a unit of work. For example, a compiler
plugin has compile
as the goal that compiles the source of the project. An illustration is as follows:
A plugin with set of goals can be executed using the following command:
mvn [pluginID:goalID]
Typically, the following are the types of plugins:
The following table consists of some of the common plugins:
Plugin |
Description |
---|---|
| |
| |
| |
| |
| |
| |
| |
| |
|
This generates the PDF version of the project documentation. |
For more plugins, navigate to http://maven.apache.org/plugins/.
Seldom are projects a single developer's asset. A project contains stakeholders, and collaboration among them is essential. Often, a lack of effective documentation has paralyzed the project, its maintenance, and its usage. Maven with its site
plugin has eased this process of having effective project documentation by generating a site and reports related to project. A site can be generated using the following command:
mvn site
The site is generated at the target/site
directory. Maven uses the Doxia component (discussed in the Maven Component Architecture section of Chapter 1, Apache Maven – Introduction and Installation) to generate documentation. The site also contains all the configured reports such as the unit test coverage, PMD report, and others. We will cover site and report generation in more detail in the Generating site documentation section of Chapter 5, Spicing Up a Maven Project.
52.14.82.217