POM stands for Project Object Model. It is primarily an XML representation of a project in a file named pom.xml
. POM is the identity of a Maven project and without it, the project has no existence. It is analogous to a Make file or a build.xml
file of Ant.
A project in a broad sense should contain more than just mere code files and should act as a one-stop shop for all the things concerning it. Maven fulfills this need using the pom
file. POM tends to answer questions such as: Where is the source code? Where are the resources? How is the packaging done? Where are the unit tests? Where are the artifacts? What is the build environment like? Who are the actors of the project? and so on.
In a nutshell, the contents of POM fall under the following four categories:
A POM file with all the categories discussed is shown as follows:
<project> <!-- The Basics Project Information--> <groupId>...</groupId> <artifactId>...</artifactId> <version>...</version> <packaging>...</packaging> <dependencies>...</dependencies> <parent>...</parent> <dependencyManagement>...</dependencyManagement> <modules>...</modules> <properties>...</properties> <!-- Build Settings --> <build>...</build> <reporting>...</reporting> <properties>...</properties> <packaging>...</packaging> <!-- More Project Information --> <name>...</name> <description>...</description> <url>...</url> <inceptionYear>...</inceptionYear> <licenses>...</licenses> <organization>...</organization> <developers>...</developers> <contributors>...</contributors> <!-- POM Relationships --> <groupId>...</groupId> <artifactId>...</artifactId> <version>...</version> <parent>...</parent> <dependencyManagement>...</dependencyManagement> <dependencies>...</dependencies> <modules>...</modules> <!-- Environment Settings --> <issueManagement>...</issueManagement> <ciManagement>...</ciManagement> <mailingLists>...</mailingLists> <scm>...</scm> <prerequisites>...</prerequisites> <repositories>...</repositories> <pluginRepositories>...</pluginRepositories> <distributionManagement>...</distributionManagement> <profiles>...</profiles> </project>
Maven coordinates define a set of identifiers that can be used to uniquely identify a project, a dependency, or a plugin in a Maven POM. Analogous to algebra where a point is identified by its coordinate in space, the Maven coordinates mark a specific place in a repository, acting like a coordinate system for Maven projects. The Maven coordinates' constituents are as follows:
junit
project. The group forms the basis for storage in the repository and acts much like a Java packaging structure does in OS. The corresponding dots are replaced with OS-specific directory separators (such as /
in Unix), which forms the relative directory structure from the base repository. For example, if groupId
is com.packt.mvneclipse
, it lives in the $M2_REPO/com/packt/mvneclipse
directory.groupId
that represents a single project/the project known by. Along with the groupId
coordinate, the artifactId
coordinate fully defines the artifact's living quarters within the repository. For example, continuing with the preceding example, the artifact ID with hello-project
resides at the $M2_REPO/com/packt/mvneclipse/hello-project
path.hello-project
with version 1.0 resides in the $M2_REPO/com/packt/mvneclipse/hello-project/1.0/
directory.jar
file. The core packaging values available in Maven are: pom
, jar
, maven-plugin
, ejb
, war
, ear
, rar
, and par
. The following figure illustrates an example of Maven coordinates:POM relationships identify the relationship they possess with respect to other modules, projects, and other POMs. This relationship could be in the form of dependencies, multimodule projects, parent-child also known as inheritance, and aggregation. The elements of POM relationships are represented graphically as shown in the following figure:
Similarly, the elements of POM relationships in the XML file can be specified as shown in the following code:
<!-- POM Relationships --> <groupId>...</groupId> <artifactId>...</artifactId> <version>...</version> <parent>...</parent> <dependencyManagement>...</dependencyManagement> <dependencies>...</dependencies> <modules>...</modules>
The most basic POM consists of just the Maven coordinates and is sufficient to build and generate a jar
file for the project. A simple POM file may look like the following code:
<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> </project>
The following points will explain these elements:
modelVersion
value is 4.0.0
. Maven supports this version of POM model.project
element and three mandatory fields: groupId
, artifactId
, and version
.pom.xml
is project
, and it has three major subnodes.A simple POM (as shown in the previous code snippet) is hardly enough in real-world projects.
Like Java, where every object inherits from java.lang.Object
, every POM inherits from a base POM known as Super POM. Implicitly, every POM inherits the default value from the base POM. It eases the developer's effort toward minimal configuration in his/her pom.xml
file. However, default values can be overridden easily when they are specified in the projects' corresponding pom
file. The default configuration of the super POM can be made available by issuing the following command inside the respective project:
mvn help:effective-pom
The super POM is a part of the Maven installation and can be found in the maven-x.y.z-uber.jar
or maven-model-builder-x.y.z.jar
file at $M2_HOME/lib
, where x.y.z
denotes the version. In the corresponding JAR file, there is a file named pom-4.0.0.xml
under the org.apache.maven.model
package.
The default configuration of the super POM inherited in a sample project is given as follows; for the sake of brevity, only some important aspects are shown:
<!--General project Information --> <modelVersion>4.0.0</modelVersion> <groupId>com.packt.mvneclipse</groupId> <artifactId>hello-project</artifactId> <version>0.0.1-SNAPSHOT</version> <name>hello-project</name> <url>http://maven.apache.org</url> <properties>1 <project.build.sourceEncoding>UTF8</project.build.sourceEncoding> </properties> <repositories> <repository> <snapshots> <enabled>false</enabled> </snapshots> <id>central</id> <name>Maven Repository Switchboard</name> <url>http://repo1.maven.org/maven2</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <releases> <updatePolicy>never</updatePolicy> </releases> <snapshots> <enabled>false</enabled> </snapshots> <id>central</id> <name>Maven Plugin Repository</name> <url>http://repo1.maven.org/maven2</url> </pluginRepository> </pluginRepositories> <!-- Build source directory and details> <build> … <sourceDirectory> ...</sourceDirectory> <scriptSourceDirectory>..</scriptSourceDirectory> <testOutputDirectory>..</testOutputDirectory> <outputDirectory>...<outputDirectory> … <finalName>hello-project-0.0.1-SNAPSHOT</finalName> <pluginManagement> <plugins> <plugin> <artifactId>maven-antrun-plugin</artifactId> <version>1.3</version> </plugin> <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>2.2-beta-5</version> </plugin> <plugin> <artifactId>maven-dependency-plugin</artifactId> <version>2.1</version> </plugin> <plugin> <artifactId>maven-release-plugin</artifactId> <version>2.0</version> </plugin> </plugins> </pluginManagement> <plugins> <!-- Plugins, phases and goals --> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>2.4.1</version> <executions> <execution> <id>default-clean</id> <phase>clean</phase> <goals> <goal>clean</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.7.2</version> <executions> <execution> <id>default-test</id> <phase>test</phase> <goals> <goal>test</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <executions> <execution> <id>default-testCompile</id> <phase>test-compile</phase> <goals> <goal>testCompile</goal> </goals> </execution> <execution> <id>default-compile</id> <phase>compile</phase> <goals> <goal>compile</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-jar-plugin</artifactId> <version>2.3.1</version> <executions> <execution> <id>default-jar</id> <phase>package</phase> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-deploy-plugin</artifactId> <version>2.5</version> <executions> <execution> <id>default-deploy</id> <phase>deploy</phase> <goals> <goal>deploy</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-site-plugin</artifactId> <version>2.0.1</version> <executions> <execution> <id>default-site</id> <phase>site</phase> <goals> <goal>site</goal> </goals> <configuration> </project>
18.223.196.146