What is POM.XML File?
The pom.xml file is the only required artifact in a Maven project. It contains information about the project and various configuration details used by Maven to build the project(s).
POM stands for Project Object Model. It is the basic element in Maven and always resides in the base directory of the project as pom.xml.
What is inside a basic POM File?
When a new Maven project is created, it asks the user to enter below information:
Once done, it creates Maven project structure that also contains POM File.
The pom.xml file is started with the project element. Then the groupId, artifactId, and version coordinates are mentioned followed by name & description.
GroupId / ArtifactID / Version
In general software terms, an “artifact” is something produced by the software development process.
In Maven terminology, an artifact is a file, generally a jar, war or other executable file that gets deployed to a Maven repository. Artifacts in Maven are identified by a coordinate system of group ID, an artifact ID and a version string. These coordinates are sometimes referred to as the GAV.
Group ID: An identifier for a collection of related modules. This is usually a hierarchy that starts with the organization that produced the modules, and then possibly moves into the increasingly more specialized project or sub-projects that the artifacts are a part of. This can also be thought of as a namespace, and is structured much like the Java package system. It is usually a reversed domain name, like com.example.projectname)
Artifact ID: The Artifact ID is a unique identifier for a given module within a group.
Version: The version is used to identify the release or build number of the project.
Maven uses the groupId, artifactId, and version to identify dependencies (usually other jar files) needed to build and run your code.
Name / Description
This is the name and description fields for the artifact/project.
How it works?
In order to build the project, Maven provides options to mention life-cycle goals and project dependencies (that rely on Maven pluging capabilities and on its default conventions).
Some of the configurations that can be specified in the POM are following:
- project dependencies
- plugins
- goals
- build profiles
- project version
- developers
- mailing list
Maven has three main groups of action for executing builds or to perform other tasks:
- Goals
The task (action) that executes. For example a goal would be to ‘package a jar file’. A goal name is often a combination of Maven plugin name (more on plugin later) and the goal name within that plugin.
Example: compile goal on Compiler plugin i.e. compiler:compile
- Phases
Phases map one or many goals that are related in a greater life cycle. For example the compile phase may call compiler:compile goal for the jar projects. Actually a phase is just for defining the order/sequence in a life cycle. Phase links to goal(s) that is the task actually being executed. In other words, when you call a phase, it will actually call a goal which is linked to that phase.
- Lifecycles
Lifecycle is a collection of related phases. Phases execute sequentially. For example, the Clean life cycle contains these phases (in order): pre-clean, clean, post-clean. When you run a phase, all phases before the target phase and the target phase itself will be executed. There are many life cycles available in Maven of which many are directed by the type of maven project being build. For example a Maven project that builds enterprise application will have different phases than a project that just builds a jar file.
In Summary:
Lifecycles contain phases
Phases map to Goals
To see what life cycles have what goals, please refer Life Cycle References.
While executing a task or goal, Maven looks for the POM in the current directory. It reads the POM, gets the needed configuration information, and then executes the goal.
Convention over Configuration
Maven uses Convention over Configuration which means Maven provides default behavior for projects. When a Maven project is created, Maven creates default project structure. Maven will look for certain project files at specific locations. This is known as Standard Directory Template
Maven will look for different type of files at below default locations:
Standard Java Source code -> {projectLocation}/src/main/java
Resource Files -> {projectLocation}/src/main/resources
Unit Tests -> {projectLocation}/src/test
Unit Test Resource Files -> {projectLocation}/src/test/resources
Distributable JAR -> {projectLocation}/target
Complied byte code -> {projectLocation}/target/classes
If you need to set alternative locations instead of using default locations you can override the default by specifying the configuration settings in your project POM file.
Maven Repository
In Maven terminology, a repository is a place i.e. directory where all the project jars, library jar, plugins or any other project specific artifacts are stored and can be used by Maven easily.
Maven repository is of three types:
- Local
- Central
- Remote
Local Repository
Maven local repository is a folder location on your machine. It gets created when you run any maven command for the first time.
Maven local repository keeps your project’s dependencies (library jars, plugin jars etc). When you run a Maven build, then Maven automatically downloads all the dependency jars into the local repository. It helps to avoid references to dependencies stored on remote machine every time a project is build.
Maven local repository by default gets created by Maven in %USER_HOME% directory.
Central Repository
Maven central repository is a repository provided by Maven community. It contains a large number of commonly used libraries. When Maven does not find any dependency in local repository, it starts searching in central repository.
You can browse the content of central maven repository on URL: https://mvnrepository.com/
Using this library, you can search all the available libraries in central repository.
Remote Repository
Remote Repository is developer’s own custom repository containing required libraries or other project jars.
Whenever a project has a dependency upon an artifact, Maven will first attempt to use a local copy of the specified artifact. If that artifact does not exist in the local repository, it will check Central Maven Repository. If artifact still not found, it will then attempt to download from a remote repository.
The repository elements within a POM specify those alternate repositories to search.
<repositories> <repository> <id>snapshots</id> <name Snapshot Repository Name</name> <url>URLForRepoGoesHere</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories>
Here you notice elements called <releases> & <snapshots>. Let’s see what does it mean…
- releases, snapshots: These are the policies for each type of artifact, Release or snapshot. With these two sets, a POM has the power to alter the policies for each type independent of the other within a single repository. For example, one may decide to enable only snapshot downloads, possibly for development purposes.
- enabled: trueor false for whether this repository is enabled for the respective type (releases or snapshots).
What is the different between Releases & Snapshot?
In Maven, there are two types of versions: releases and snapshots (those that end in -SNAPSHOT). A snapshot should always be used by your projects during development as it has a special meaning to Maven to indicate that development is still occurring and that the project may change. A release is assumed never to change, so release versions (such as 1.1, 2.0, or3.0-beta-5) should only be used for a single state of the project when it is released, and then updated to the next snapshot.
Plug-ins
Plug-ins provides default behavior and functionality in Maven. We can think of Maven as engine that provides all functionality through plug-ins. A plugin is a self-contained piece of reusable functionality for incorporating into the lifecycle of one or more Maven projects.
There are mainly two main types of plugins in Maven: build plugins, used for all tasks related to the build process of the project; and reporting plugins, used for obtaining a visual representation of the state of the project.
Maven obtains plugins in the same way as it retrieves other project dependencies; by downloading their artifact and associated dependencies from a remote repository. There are hundreds of Maven plug-ins available that can be used to carry out tasks ranging from code compilation to packaging to project documentation generation.
Maven comes with a basic set of plug-ins to get started. Many common/core plug-ins are simply known to Maven and downloaded when needed. Other plug-ins explicitly needs to be mentioned in your project POM file if you want to use them. If you want to change the default behavior of plug-ins you can specify various options within your project’s POM file within <configuration> tags as shown below.
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin>
Note: An important fact to notice about maven-compiler-plugin. This plugin is compiled by default for Java version 1.5. If you want to use features from newer version you need to mention the version within <source> & <target> tags.
Plugin Repositories
Maven plugins are themselves a special type of artifact. Because of this, plugin repositories may be separated from other repositories. The structure of the pluginRepositories element block is similar to the repositories element. The pluginRepository elements specify a remote location where Maven can find new plugins.
Plugin Management
- pluginManagement: is an element that is seen alongside plugins. Plugin Management contains plugin elements in much the same way, except that rather than configuring plugin information for this particular project build, it is intended to configure project builds that inherit from this one. However, this only configures plugins that are actually referenced within the plugins element in the children. The children have every right to override pluginManagement
<pluginManagement> <plugins> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>2.6</version> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.12.4</version> </plugin> </plugins> </pluginManagement>
Build Element
In Maven, the build is run using a predefined, ordered set of steps called the build lifecycle. The individual steps are called phases, and the same phases are run for every Maven build using the default lifecycle, no matter what it will produce.
Some of the most commonly used lifecycle phases in the default lifecycle are:
- validate— checks build prerequisites
- compile—compiles the source code identified for the build
- test— runs unit tests for the compiled code
- package— assembles the compiled code into a binary build result
- install— shares the build with other projects on the same machine
- deploy—publishes the build into a remote repository for other projects to use
The phases are designed to be run in sequence so that they can depend on the results of the previous phases. For example, choosing to run the test phase will first run validate, compile, and the other intermediate phases to ensure that the compiled code is up-to-date before running the tests.
In addition to the default build lifecycle mentioned above, Maven has two other lifecycles built-in:
- Clean lifecycle:The command mvn clean is often used to remove Maven’s work directory called target. However, as some plugins can generate information that does not reside in the work area, it is possible for them to bind to the clean lifecycle to clean up after themselves as well.
The complete list of phases in the Clean lifecycle is pre-clean, clean, and post-clean.
- Site lifecycle:While much of the site generation is coordinated by Maven’s reporting mechanism, it is also possible to bind plugins to be executed as part of the site generation lifecycle. The phases available are pre-site, site, post-site, and site-deploy.
Directories
The set of directory elements live in the parent build element, which set various directory structures for the POM as a whole. Since they do not exist in profile builds, these cannot be altered by profiles.
<build> <sourceDirectory>${basedir}/src/main/java</sourceDirectory> <scriptSourceDirectory>${basedir}/src/main/scripts</scriptSourceDirectory> <testSourceDirectory>${basedir}/src/test/java</testSourceDirectory> <outputDirectory>${basedir}/target/classes</outputDirectory> <testOutputDirectory>${basedir}/target/test-classes</testOutputDirectory> </build>
If the values of a *Directory element above is set as an absolute path (when their properties are expanded) then that directory is used. Otherwise, it is relative to the base build directory: ${basedir}.
Dependencies
One of the main strength of Maven is its dependency management. Mostly every project depends upon others to build and run correctly. Maven downloads and links the dependencies for you on compilation and other goals that require them. Maven also brings in the dependencies of those dependencies (transitive dependencies), allowing your list to focus solely on the dependencies your project requires. Maven downloads all dependencies to a folder .m2/repository in the user’s home directory (i.e. C:\users\[your user name]\.m2\repository on Windows.
If you want to change the folder to another directory, you can put a Maven configuration file settings.xml in the .m2 directory. You can find a sample file in your Maven distribution in the conf directory. Then look for the entry localRepository which should be commented out like this:
<!-- localRepository | The path to the local repository maven will use to store artifacts. | Default: ${user.home}/.m2/repository <localRepository>/path/to/local/repo</localRepository> -->
Activate it and set it to the path you like, for e.g. to make Maven download the dependencies to D:\myMavenRepository set it as below
<localRepository>D:/myMavenRepository</localRepository>
If you want to see the dependency tree for a given project, use below plugin
mvn dependency:tree
Examples:
Here are some example dependencies used in POM file usually used in automation projects:
Apache Maven Deploy Plugin
The deploy plugin is primarily used during the deploy phase, to add your artifact(s) to a remote repository for sharing with other developers and projects. This is usually done in an integration or release environment.
<dependency> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-deploy-plugin</artifactId> <version>2.7</version> </dependency>
Selenium Java Client
Provides language binding for java to work with Selenium Webdriver using Java language.
<dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>3.0.1</version> </dependency>
POI
Apache POI is a popular API that allows programmers to create, modify, and display MS Office files using Java programs.
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.14</version> </dependency>
PDFBox
The Apache PDFBox library is an open source Java tool for working with PDF documents.
<dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>1.8.9</version> </dependency>
Appium – JVM
Provides Java language binding for Appium
<dependency> <groupId>io.appium</groupId> <artifactId>java-client</artifactId> <version>4.1.2</version> </dependency>
Distribution Management
Distribution management manages the distribution of the artifact and supporting files generated throughout the build process.
- downloadUrl: is the url of the repository from where another POM may point to in order to grab this POM’s artifact.
<distributionManagement> <repository> <id>internalRepoId</id> <url>URLForRepoGoesHere</url> </repository> </distributionManagement>
<repository> Element:
In POM the repository element specifies the location and manner in which Maven may download remote artifacts for use by the current project, whereas, distributionManagement specifies where (and how) this project will get to a remote repository when it is deployed. The repository elements will be used for snapshot distribution if the snapshotRepository is not defined.
- id, name: The idis used to uniquely identify this repository amongst many, and the name is a human readable form.
- uniqueVersion: The unique version takes a trueor false value to denote whether artifacts deployed to this repository should get a uniquely generated version number, or use the version number defined as part of the address.
- url: This is the core of the repository element. It specifies both the location and the transport protocol to be used to transfer a built artifact (and POM file, and checksum data) to the repository.
What is Apache Archiva?
You can use Apache Archiva as a centralized location to store your internal dependencies or artifacts. It is a popular open source repository manager. It is simply a web application where you can host, store and manage your enterprise build artifact repositories. Aside from managing artifact repositories, Archiva also provides features such as on-demand remote repository proxying, artifact searching and browsing, reporting and security access control.
It allows repositories to be grouped and accessed via a single URL.
Like most repository managers, deployment to Archiva is a protected operation. You provide the credentials needed to interact with Archive in the settings.xml file.
What are Archetypes?
Maven makes it very simple to start a new project with archetypes. An archetype is a template project for a particular type of module, which ranges from a simple JAR or WAR module to a more complete template application for many popular frameworks. Archetypes extend the Maven concept of building on conventions by allowing them to be shared in reusable chunks.
Getting Help
To list the available command line parameters, you can use the following command line option:
-h, –help
Please comment with your real name using good manners.